题目背景
小卡正在新家的客厅中看电视。电视里正在播放放了千八百次依旧重播的《亮剑》,剧中李云龙带领的独立团在一个县城遇到了一个鬼子小队,于是独立团与鬼子展开游击战。
题目描述
描述 县城里有n个用地道相连的房子,第i个只与第i-1和第i+1个相连。这是有m个消息依次传来
1、消息为D x:鬼子将x号房子摧毁了,地道被堵上。
2、消息为R :村民们将鬼子上一个摧毁的房子修复了。
3、消息为Q x:有一名士兵被围堵在x号房子中。
李云龙收到信息很紧张,他想知道每一个被围堵的士兵能够到达的房子有几个。
输入格式
第一行2个整数n,m(n,m<=50000)。
接下来m行,有如题目所说的三种信息共m条。
输出格式
对于每一个被围堵的士兵,输出该士兵能够到达的房子数。
输入
输入
7 9
D 3
D 6
D 5
Q 4
Q 5
R
Q 4
R
Q 4
输出
1
0
2
4
说明/提示
若士兵被围堵在摧毁了的房子中,那只能等死了。。。。。。
这道题我们可以将每一个摧毁的村庄编号加入平衡树中,然后我们在询问时,找到询问的编号的前驱和后继就可以啦,如果这个村庄已经被删除了,那么就可以直接输出0,因为提示[雾]。
代码:
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 7;
std::mt19937 rnd(233);
struct treap
{
int l, r, size, val, key;
}t[maxn];
int cnt, root;
inline int newnode(int val)
{
t[++cnt] = treap{0, 0, 1, val, rnd()};
return cnt;
}
inline void update(int now)
{
t[now].size = t[t[now].l].size + t[t[now].r].size + 1;
}
inline void split(int now,int val,int &x,int &y)
{
if(!now){
x = y = 0;
return;
}
if(t[now].val<=val){
x = now;
split(t[now].r, val, t[now].r, y);
}
else{
y = now;
split(t[now].l, val, x, t[now].l);
}
update(now);
}
inline int merge(int x,int y)
{
if(!x||!y)
return x + y;
if(t[x].key>t[y].key){
t[x].r = merge(t[x].r, y);
update(x);
return x;
}
else{
t[y].l = merge(x, t[y].l);
update(y);
return y;
}
}
int x, y, z;
inline void insert(int val)
{
split(root, val, x, y);
root = merge(merge(x, newnode(val)), y);
}
inline void del(int val)
{
split(root, val, x, z);
split(x, val - 1, x, y);
y = merge(t[y].l, t[y].r);
root = merge(merge(x, y), z);
}
inline int pre(int val)
{
split(root, val, x, y);
int now = x;
while(t[now].r){
now = t[now].r;
}
root = merge(x, y);
return t[now].val;
}
inline int nex(int val)
{
split(root, val, x, y);
int now = y;
while(t[now].l){
now = t[now].l;
}
root = merge(x, y);
return t[now].val;
}
inline void read(int &val)
{
val = 0;
int f = 1;
char c = getchar();
while(c<'0' || c>'9'){
if(c=='-')
f = -1;
c = getchar();
}
while(c<='9' && c>='0'){
val = val * 10 + c - '0';
c = getchar();
}
val *= f;
}
char s[2];
int st[maxn], top, vis[maxn];
int main()
{
int n, m;
read(n), read(m);
insert(0), insert(n + 1);
while(m--){
scanf("%s", s);
int num;
if(s[0]=='D'){
read(num);
insert(num);
vis[num] = 1;
st[++top] = num;
}
else if(s[0]=='R'){
del(st[top]);
vis[st[top]] = 0;
top--;
}
else{
read(num);
if(vis[num]){
cout << 0 << endl;
continue;
}
int l = pre(num), r = nex(num);
cout << r - l - 1 << endl;
}
}
}