[洛谷1053] 鬼子進村

題目背景

小卡正在新家的客廳中看電視。電視里正在播放放了千八百次依舊重播的《亮劍》,劇中李雲龍帶領的獨立團在一個縣城遇到了一個鬼子小隊,因而獨立團與鬼子展開游擊戰。數組

題目描述

描述 縣城裏有n個用地道相連的房子,第i個只與第i-1和第i+1個相連。這是有m個消息依次傳來spa

一、消息爲D x:鬼子將x號房子摧毀了,地道被堵上。code

二、消息爲R :村民們將鬼子上一個摧毀的房子修復了。blog

三、消息爲Q x:有一名士兵被圍堵在x號房子中。io

李雲龍收到信息很緊張,他想知道每個被圍堵的士兵可以到達的房子有幾個。class

輸入輸出格式

輸入格式:

第一行2個整數n,m(n,m<=50000)。查詢

接下來m行,有如題目所說的三種信息共m條。top

輸出格式:

對於每個被圍堵的士兵,輸出該士兵可以到達的房子數。di

輸入輸出樣例

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

說明

若士兵被圍堵在摧毀了的房子中,那隻能等死了。。。。。。while

思路

一個平衡樹,內部儲存被破壞的房子,支持添加刪除,查詢前驅後繼便可;

一個布爾數組,儲存每一個房子的毀壞狀況;

一個棧,記錄毀壞房子的順序;

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

相關文章
相關標籤/搜索