P1503

鬼子进村

题目背景

小卡正在新家的客厅中看电视。电视里正在播放放了千八百次依旧重播的《亮剑》,剧中李云龙带领的独立团在一个县城遇到了一个鬼子小队,于是独立团与鬼子展开游击战。

题目描述

县城里有 \(n\) 个用地道相连的房子,第 \(i\) 个只与第 \(i-1\) 和第 \(i+1\) 个相连。这时有 \(m\) 个消息依次传来:

  1. 若消息为 D x:鬼子将 \(x\) 号房子摧毁了,地道被堵上。

  2. 若消息为 R :村民们将鬼子上一个摧毁的房子修复了。

  3. 若消息为 Q x:有一名士兵被围堵在 \(x\) 号房子中。

李云龙收到信息很紧张,他想知道每一个被围堵的士兵能够到达的房子有几个。

输入格式

第一行两个整数 \(n,m\)

接下来 \(m\) 行,有如题目所说的三种信息共 \(m\) 条。

输出格式

对于每一个被围堵的士兵,输出该士兵能够到达的房子数。

样例 #1

样例输入 #1

7 9
D 3
D 6
D 5
Q 4
Q 5
R
Q 4
R
Q 4

样例输出 #1

1
0
2
4

提示

\(1\leq n,m\leq 5\times 10^4\)

若士兵被围堵在摧毁了的房子中,那只能等死了。。。。。。

我们维护炸毁的房子的编号

这样Q操作等价于查找前后驱

自然想到 万能的STL 但是有 R操作需要删除已插入的编号 所以只能用tree

#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
#define int long long
#define SILENCE_SUZUKA 无声铃鹿
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>Tree;
const int N=5e4+5;
int n,m;
int stack_[N],pt,vis[N];
Tree tr;
#ifdef SILENCE_SUZUKA
signed main() {
	ios::sync_with_stdio(false);
	cin>>n>>m;
	tr.insert(0);
	tr.insert(n+1);
	for(int i=1; i<=m; i++) {
		char op;
		int x;
		cin>>op;
		if(op=='D') {
			cin>>x;
			stack_[++pt]=x;
			vis[x]=1;
			tr.insert(x);
		}
		if(op=='R') {
			int x=stack_[pt];
			tr.erase(x);
			vis[x]=0;
			pt--;
		}
		if(op=='Q') {
			cin>>x;
			if(vis[x])cout<<0<<"\n";
			else {
				//pre after
				auto it1=tr.lower_bound(x);
				it1--;
				auto it2=tr.upper_bound(x);
				int a=*it1,b=*it2;
				cout<<b-a-1<<"\n";
			}
		}
	}
	return 1+1==3;
}
#endif
posted @ 2023-05-06 09:23  N0zoM1z0  阅读(7)  评论(0编辑  收藏  举报