题目描述
县城里有
n
n
n 个用地道相连的房子,第
i
i
i 个只与第
i
−
1
i−1
i−1 和第
i
+
1
i+1
i+1 个相连。
这时有
m
m
m 个消息依次传来:
若消息为 D x:鬼子将 x x x 号房子摧毁了,地道被堵上。
若消息为 R :村民们将鬼子上一个摧毁的房子修复了。
若消息为 Q x:有一名士兵被围堵在 x x x 号房子中。
李云龙收到信息很紧张,他想知道每一个被围堵的士兵能够到达的房子有几个。
输入格式
第一行两个整数 n,m。
接下来 m 行,有如题目所说的三种信息共 m 条。
输出格式
对于每一个被围堵的士兵,输出该士兵能够到达的房子数。
思路
房子是一条链
删除的房子先毁后建
就是说已毁掉的房子的位置集合是个栈
查询时要输出的是两侧最近的已毁房屋的距离差减一
就可以用个平衡树放在已毁房屋的位置集合上
减小查前驱后缀的复杂度
代码
#include<cstdio>
#include<cstdlib>
#include<ctime>
#define INF 0x3fffffff
using namespace std;
struct NODE{
int val,l,r,cnt,size,f;
}node[100039];
char opt;
bool bb[50004];
int k,root,n,m,x,de[50004],t;
int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
void pushup(int p){node[p].size=node[p].cnt+node[node[p].l].size+node[node[p].r].size;}
int newnode(int x){
node[++k].val=x;
node[k].cnt=node[k].size=1;
node[k].f=rand();
return k;
}
void zag(int &p){
int k=node[p].l;
node[p].l=node[k].r,node[k].r=p,p=k;
pushup(node[p].r);pushup(p);
}
void zig(int &p){
int k=node[p].r;
node[p].r=node[k].l,node[k].l=p,p=k;
pushup(node[p].l);pushup(p);
}
void insert(int &p,int x){
if(!p)p=newnode(x);
else if(x==node[p].val)node[p].cnt++,node[p].size++;
else if(x<node[p].val){
insert(node[p].l,x);
if(node[node[p].l].f<node[p].f)zag(p);
}
else{
insert(node[p].r, x);
if(node[node[p].r].f<node[p].f)zig(p);
}
pushup(p);
}
void erase(int &p,int x){
if(node[p].val==x){
if(node[p].cnt>1)node[p].cnt--;
else{
if(!node[p].l)p=node[p].r;
else if(!node[p].r)p=node[p].l;
else if(node[node[p].l].f<node[node[p].r].f)zag(p),erase(node[p].r,x);
else zig(p),erase(node[p].l,x);
}
}
else if(node[p].val>x)erase(node[p].l,x);
else erase(node[p].r,x);
pushup(p);
}
int get_pre(int p,int x){
if(!p)return -INF;
else if(node[p].val<x)return max(node[p].val,get_pre(node[p].r,x));
else return get_pre(node[p].l,x);
}
int get_nex(int p,int x){
if(!p)return INF;
else if(x<node[p].val)return min(node[p].val,get_nex(node[p].l,x));
else return get_nex(node[p].r,x);
}
int main(){
srand((unsigned int)time(0));
scanf("%d%d",&n,&m);
newnode(0);newnode(n+1);
root=1;node[1].r=2;pushup(1);
while(m--){
scanf(" %c ",&opt);
if(opt=='D'){
scanf("%d",&x);
bb[x]=1;
de[++t]=x;
insert(root,x);
}
if(opt=='R'){
erase(root,de[t]);
bb[de[t]]=0;
de[t--];
}
if(opt=='Q'){
scanf("%d",&x);
if(bb[x])printf("0\n");
else printf("%d\n",get_nex(root,x)-get_pre(root,x)-1);
}
}
return 0;
}