1. 程式人生 > >[洛谷1053] 鬼子進村

[洛谷1053] 鬼子進村

破壞 print %d bool 接下來 gpo cst 一個棧 ret

題目背景

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

題目描述

描述 縣城裏有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

[洛谷1053] 鬼子進村