[洛谷1053] 鬼子进村

题目背景

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

题目描述

描述 县城里有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条。

输出格式:

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

输入输出样例

输入样例#1: 
7 9
D 3
D 6
D 5
Q 4
Q 5
R
Q 4
R
Q 4
输出样例#1: 
1
0
2
4

说明

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

思路

一个平衡树,内部储存被破坏的房子,支持添加删除,查询前驱后继即可;

一个布尔数组,储存每个房子的毁坏情况;

一个栈,记录毁坏房子的顺序;

ans如果房子毁坏为0,否则为后继-前驱-1;

代码实现

 1 #include<cstdio>
 2 const int maxn=5e4+10;
 3 int rt,ts;
 4 int t[maxn];
 5 int f[maxn],s[maxn][2];
 6 void rot(int x){
 7     int y=f[x],z=f[y],l,r;
 8     l=s[y][0]==x?0:1,r=l^1;
 9     if(y!=rt) s[z][s[z][1]==y]=x;
10     f[x]=z,f[y]=x,f[s[x][r]]=s[x][r]!=0?y:0;
11     s[y][l]=s[x][r],s[x][r]=y;
12 }
13 void splay(int x){
14     int y,z;
15     while(x!=rt){
16         y=f[x],z=f[y];
17         if(y==rt) rot(x),rt=x;
18         else{
19             rot((s[z][0]==y)==(s[y][0]==x)?y:x),rot(x);
20             if(z==rt) rt=x;
21         }
22     }
23 }
24 void ins(int k,int x){
25     int fa=0;
26     while(k&&t[k]!=x) fa=k,k=s[k][x>t[k]];
27     k=s[fa][x>t[fa]]=++ts;
28     t[k]=x,f[k]=fa;
29     splay(k);
30 }
31 void del(int k,int x){
32     while(t[k]!=x) k=s[k][x>t[k]];
33     splay(k);
34     rt=x=s[k][0];
35     while(s[x][1]) x=s[x][1];
36     s[x][1]=s[k][1],f[s[k][1]]=x;
37 }
38 int in_x(int k,int x,int now){
39     if(!k) return now;
40     if(x>t[k]) return in_x(s[k][1],x,t[k]);
41     else return in_x(s[k][0],x,now);
42 }
43 int ax_x(int k,int x,int now){
44     if(!k) return now;
45     if(x<t[k]) return ax_x(s[k][0],x,t[k]);
46     else return ax_x(s[k][1],x,now);
47 }
48 int n,m,x;
49 int q[maxn],top;
50 bool v[maxn];
51 char ch[3];
52 int main(){
53     scanf("%d%d",&n,&m);
54     rt=++ts,t[rt]=n+2,ins(rt,1);
55     while(m--){
56         scanf("%s",ch);
57         if(ch[0]=='D'){
58             scanf("%d",&x);
59             v[q[++top]=x]=1;
60             ins(rt,x+1);
61         }
62         if(ch[0]=='R'){
63             v[x=q[top--]]=0;
64             del(rt,x+1);
65         }
66         if(ch[0]=='Q'){
67             scanf("%d",&x);
68             if(v[x]) puts("0");
69             else printf("%d\n",ax_x(rt,x+1,0)-in_x(rt,x+1,0)-1);
70         }
71     }
72     return 0;
73 }

//自己yy的想法T了,就懒得写,直接粘了板子QuQ

posted @ 2017-12-23 19:54  J_william  阅读(382)  评论(0编辑  收藏  举报