P1503
鬼子进村
题目背景
小卡正在新家的客厅中看电视。电视里正在播放放了千八百次依旧重播的《亮剑》,剧中李云龙带领的独立团在一个县城遇到了一个鬼子小队,于是独立团与鬼子展开游击战。
题目描述
县城里有 \(n\) 个用地道相连的房子,第 \(i\) 个只与第 \(i-1\) 和第 \(i+1\) 个相连。这时有 \(m\) 个消息依次传来:
-
若消息为
D x
:鬼子将 \(x\) 号房子摧毁了,地道被堵上。 -
若消息为
R
:村民们将鬼子上一个摧毁的房子修复了。 -
若消息为
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