hdu 1540 Tunnel Warfare

题目描述:给定连续的n个村庄,有三种操作:

        1.D x:毁掉第x个村庄;

        2.Q x:询问直接或间接与x相连的村庄数目

        3.R :恢复上一个被毁掉的村庄。

分析:用线段树维护区间内以左端点开始的连续区间,以右端点结束的连续区间。

   询问我拆成了两部分,一个是询问x向右(含x)的连续区间长,一个是询问x向左(含x)的连续区间长,加和减一就是答案。

   操作三用个栈记录下就行。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #define N 50010
 6 #define lson l,m,n<<1
 7 #define rson m+1,r,n<<1|1
 8 using namespace std;
 9 int s[N<<2][2];
10 int x[N];
11 int stack[N];
12 void pushup(int n,int m){
13     s[n][0]=s[n<<1][0];
14     if(s[n][0]==(m-(m>>1)))s[n][0]+=s[n<<1|1][0];
15     s[n][1]=s[n<<1|1][1];
16     if(s[n][1]==(m>>1))s[n][1]+=s[n<<1][1];
17 }
18 void build(int l,int r,int n){
19     s[n][0]=s[n][1]=r-l+1;
20     if(l==r)return;
21     int m=(l+r)>>1;
22     build(lson);
23     build(rson);
24 }
25 void update(int nn,int f,int l,int r,int n){
26     if(l==r){
27         s[n][0]=s[n][1]=f;
28         return;
29     }
30     int m=(l+r)>>1;
31     if(nn<=m)update(nn,f,lson);
32     else update(nn,f,rson);
33     pushup(n,r-l+1);
34 }
35 int queryl(int nn,int l,int r,int n){
36     if(l+s[n][0]-1>=nn)return l+s[n][0]-nn;
37     int m=(l+r)>>1;
38     if(nn<=m){
39         int a=queryl(nn,lson);
40         if(a==(m-nn+1))a+=s[n<<1|1][0];
41         return a;
42     }
43     else
44         return queryl(nn,rson);
45 }
46 int queryr(int nn,int l,int r,int n){
47     if(r-s[n][1]+1<=nn)return nn-r+s[n][1];
48     else{
49         int m=(l+r)>>1;
50         if(nn<=m)return queryr(nn,lson);
51         else{
52             int a=queryr(nn,rson);
53             if(a==(nn-m))a+=s[n<<1][1];
54             return a;
55         }
56     }
57 }
58 int main(){
59     int n,m;
60     while(~scanf("%d%d",&n,&m)){
61         build(1,n,1);
62         memset(x,1,sizeof(x));
63         char op[5];
64         int a,top=0;
65         while(m--){
66             scanf("%s",op);
67             if(op[0]=='D'){
68                 scanf("%d",&a);
69                 update(a,0,1,n,1);
70                 stack[++top]=a;
71                 x[a]=0;
72             }else if(op[0]=='Q'){
73                 scanf("%d",&a);
74                 if(x[a]==0)puts("0");
75                 else
76                 printf("%d\n",queryl(a,1,n,1)+queryr(a,1,n,1)-1);
77             }else{
78                 update(stack[top],1,1,n,1);
79                 x[stack[top]]=1;
80                 --top;
81             }
82         }
83     }
84     return 0;
85 }
posted @ 2012-10-16 12:43  silver__bullet  阅读(222)  评论(0编辑  收藏  举报