题目:http://poj.org/problem?id=2892
思路:用treel,treer记录与区间左右端点相连的空白区间大小,然后更新。。。。
代码:
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 const int maxn=50010; 6 int treel[maxn*4];//从左边延伸的长度 7 int treer[maxn*4];//从右边延伸的长度 8 int st[maxn]; 9 void build(int l,int r,int w) 10 { 11 treel[w]=treer[w]=r-l+1; 12 if(l==r) 13 return ; 14 int m=(l+r)/2; 15 build(l,m,w*2); 16 build(m+1,r,w*2+1); 17 } 18 void update(int l,int r,int w,int a,int op) 19 { 20 if(l==r&&l==a) 21 { 22 if(op==1) 23 { 24 treel[w]=0; 25 treer[w]=0; 26 } 27 else 28 { 29 treel[w]=1; 30 treer[w]=1; 31 } 32 return ; 33 } 34 int m=(l+r)/2; 35 if(a<=m) 36 update(l,m,w<<1,a,op); 37 else 38 update(m+1,r,w<<1|1,a,op); 39 treel[w]=treel[w*2]; 40 treer[w]=treer[w*2+1]; 41 if(treel[w*2]==m-l+1) 42 treel[w]+=treel[w*2+1]; 43 if(treel[w*2+1]==r-m) 44 treer[w]+=treer[w*2]; 45 } 46 int query(int l,int r,int w,int a) 47 { 48 if(treel[w]==r-l+1) 49 return treel[w]; 50 if(l==r) 51 return 0; 52 int m=(l+r)/2; 53 if(a<=m) 54 { 55 if(m-treer[w*2]<a) 56 return treer[w*2]+treel[w*2+1]; 57 58 return query(l,m,w*2,a); 59 } 60 else 61 { 62 if(m+1+treel[2*w+1]>a) 63 return treer[w*2]+treel[w*2+1]; 64 65 return query(m+1,r,w*2+1,a); 66 } 67 return -1; 68 } 69 int main() 70 { 71 int n,m; 72 while(scanf("%d%d",&n,&m)!=EOF) 73 { 74 build(1,n,1); 75 int top=0; 76 while(m--) 77 { 78 char c; 79 int a; 80 getchar(); 81 scanf("%c",&c); 82 if(c!='R') 83 { 84 scanf("%d",&a); 85 if(c=='Q') 86 { 87 printf("%d ",query(1,n,1,a)); 88 } 89 else 90 { 91 st[top]=a; 92 top++; 93 update(1,n,1,a,1); 94 } 95 } 96 else 97 { 98 top--; 99 update(1,n,1,st[top],2); 100 101 } 102 } 103 } 104 return 0; 105 }