Sequence operation HDU 3397

 

题意:一串0,1代码,5中操作:

0 a b change all characters into '0's in [a , b]
1 a b change all characters into '1's in [a , b]
2 a b change all '0's into '1's and change all '1's into '0's in [a, b]
Output operations:
3 a b output the number of '1's in [a, b]
4 a b output the length of the longest continuous '1' string in [a , b]

题解:线段树的各种操作:区间更新+区间合并+延迟标记。。。

每个节点记录八个值:lsum0,rsum0,msum0,lsum1,rsum1,msum1,num,cov.分别为区间左端连续0的个数,区间右端连续0的个数,区间连续0的最大个数,和区间左端连续1的个数,区间右端连续1的个数,区间最大连续1的个数以及区间1的总个数和区间覆盖情况。

这题算是一个小小的总结了吧。。。题目很简单,但是因为之前有些东西还没有特别熟练,所以写代码的时候出现了个很难发现的bug,一直WA啊,RE的,所以找了很长很长时间才排除掉。。。这里记录一下,以示警醒。

之前的错误代码问题出现在更新操作2上,即异或操作。

 1 void updata(int L,int R,int op,int l,int r,int rt){
 2     if(L<=l&&r<=R){
 3         int m=r-l+1;
 4         if(op==0){
 5             lsum1[rt]=rsum1[rt]=msum1[rt]=num[rt]=0;
 6             lsum0[rt]=rsum0[rt]=msum0[rt]=m;
 7             cov[rt]=0;
 8         }
 9         else if(op==1){
10             lsum1[rt]=rsum1[rt]=msum1[rt]=num[rt]=m;
11             lsum0[rt]=rsum0[rt]=msum0[rt]=0;
12             cov[rt]=1;
13         }
14         else{//错误就出现在这。。。
15             if(l==r){
16                 XOR(l,r,rt);
17                 return ;
18             }
19             if(cov[rt]!=-1)pushDown(l,r,rt);
20             XOR(l,r,rt);
21             cov[rt]=2;
22         }
23         return ;
24     }
25     int m=(l+r)>>1;
26     if(cov[rt]!=-1) pushDown(l,r,rt);
27     if(R<=m) updata(L,R,op,lson);
28     else if(L>m) updata(L,R,op,rson);
29     else{
30         updata(L,R,op,lson);
31         updata(L,R,op,rson);
32     }
33     pushUp(rt,r-l+1);
34 }

之前我认为在进行2操作时只要先进行pushDown在XOR即可,实际上这是有问题的:因为下次再pushDown时就会把上次pushDown传递下去的结果覆盖掉!因此对于更新时的XOR操作正确的做法是:先XOR当前区间,再修改cov[]的值。当cov[rt]为0是改为1,为0是改为1为2时改为-1,为-1时改为2。

即如下:

 1 void updata(int L,int R,int op,int l,int r,int rt){
 2     if(L<=l&&r<=R){
 3         int len=r-l+1;
 4         if(op==0){
 5             lsum1[rt]=rsum1[rt]=msum1[rt]=num[rt]=0;
 6             lsum0[rt]=rsum0[rt]=msum0[rt]=len;
 7             cov[rt]=0;
 8         }
 9         else if(op==1){
10             lsum1[rt]=rsum1[rt]=msum1[rt]=num[rt]=len;
11             lsum0[rt]=rsum0[rt]=msum0[rt]=0;
12             cov[rt]=1;
13         }
14         else{//改成这样:
15             XOR(rt,len);
16             if(cov[rt]==0)      cov[rt]=1;
17             else if(cov[rt]==1) cov[rt]=0;
18             else if(cov[rt]==-1)cov[rt]=2;
19             else                cov[rt]=-1;
20         }
21         return ;
22     }
23     if(cov[rt]!=-1) pushDown(rt,r-l+1);
24     int m=(l+r)>>1;
25     if(R<=m) updata(L,R,op,lson);
26     else if(L>m) updata(L,R,op,rson);
27     else{
28         updata(L,R,op,lson);
29         updata(L,R,op,rson);
30     }
31     pushUp(rt,r-l+1);
32 }

当然其他地方涉及到XOR的操作也要进行相应的修改啦。。。

具体代码如下(操作比较多,所以代码就有点长啦~~~)

 

  1 #include<cstdio>
  2 #include<cmath>
  3 #include<iostream>
  4 #include<algorithm>
  5 #define lson l,m,rt<<1
  6 #define rson m+1,r,rt<<1|1
  7 using namespace std;
  8 
  9 const int maxn=1000005;
 10 int lsum1[maxn<<2],rsum1[maxn<<2],msum1[maxn<<2],lsum0[maxn<<2],rsum0[maxn<<2],msum0[maxn<<2],num[maxn<<2],cov[maxn<<2];
 11 
 12 int max(int a,int b){
 13     return a>b?a:b;
 14 }
 15 
 16 int min(int a,int b){
 17     return a<b?a:b;
 18 }
 19 
 20 void pushUp(int rt,int len){
 21     lsum1[rt]=lsum1[rt<<1];
 22     rsum1[rt]=rsum1[rt<<1|1];
 23     msum1[rt]=max(msum1[rt<<1],msum1[rt<<1|1]);
 24 
 25     lsum0[rt]=lsum0[rt<<1];
 26     rsum0[rt]=rsum0[rt<<1|1];
 27     msum0[rt]=max(msum0[rt<<1],msum0[rt<<1|1]);
 28 
 29     num[rt]=num[rt<<1]+num[rt<<1|1];
 30     
 31     if(lsum1[rt]==len-(len>>1)) lsum1[rt]+=lsum1[rt<<1|1];
 32     if(rsum1[rt]==(len>>1))     rsum1[rt]+=rsum1[rt<<1];
 33     if(lsum0[rt]==len-(len>>1)) lsum0[rt]+=lsum0[rt<<1|1];
 34     if(rsum0[rt]==(len>>1))     rsum0[rt]+=rsum0[rt<<1];
 35     msum1[rt]=max(msum1[rt],lsum1[rt<<1|1]+rsum1[rt<<1]);
 36     msum0[rt]=max(msum0[rt],lsum0[rt<<1|1]+rsum0[rt<<1]);
 37 }
 38 
 39 void build(int l,int r,int rt){
 40     cov[rt]=-1;
 41     if(l==r){
 42         int x;
 43         scanf("%d",&x);
 44         lsum1[rt]=rsum1[rt]=msum1[rt]=num[rt]=x?1:0;
 45         lsum0[rt]=rsum0[rt]=msum0[rt]=x?0:1;
 46         return ;
 47     }
 48     int m=(l+r)>>1;
 49     build(lson);
 50     build(rson);
 51     pushUp(rt,r-l+1);
 52 }
 53 
 54 void XOR(int rt,int len){
 55     swap(lsum0[rt],lsum1[rt]);
 56     swap(rsum0[rt],rsum1[rt]);
 57     swap(msum0[rt],msum1[rt]);
 58     num[rt]=len-num[rt];
 59 }
 60 
 61 void pushDown(int rt,int len){
 62     if(cov[rt]==0){
 63         lsum1[rt<<1]=rsum1[rt<<1]=msum1[rt<<1]=num[rt<<1]=lsum1[rt<<1|1]=rsum1[rt<<1|1]=msum1[rt<<1|1]=num[rt<<1|1]=0;
 64         lsum0[rt<<1]=rsum0[rt<<1]=msum0[rt<<1]=len-(len>>1);
 65         lsum0[rt<<1|1]=rsum0[rt<<1|1]=msum0[rt<<1|1]=(len>>1);
 66         cov[rt<<1]=cov[rt<<1|1]=cov[rt];
 67         cov[rt]=-1;
 68     }
 69     else if(cov[rt]==1){
 70         lsum1[rt<<1]=rsum1[rt<<1]=msum1[rt<<1]=len-(len>>1);
 71         lsum1[rt<<1|1]=rsum1[rt<<1|1]=msum1[rt<<1|1]=(len>>1);
 72         lsum0[rt<<1]=rsum0[rt<<1]=msum0[rt<<1]=lsum0[rt<<1|1]=rsum0[rt<<1|1]=msum0[rt<<1|1]=0;
 73         num[rt<<1]=len-(len>>1);num[rt<<1|1]=(len>>1);
 74         cov[rt<<1]=cov[rt<<1|1]=cov[rt];
 75         cov[rt]=-1;
 76     }
 77     else{
 78         XOR(rt<<1,len-(len>>1));
 79         if(cov[rt<<1]==0) cov[rt<<1]=1;
 80         else if(cov[rt<<1]==1) cov[rt<<1]=0;
 81         else if(cov[rt<<1]==2) cov[rt<<1]=-1;
 82         else cov[rt<<1]=2;
 83 
 84         XOR(rt<<1|1,(len>>1));
 85         if(cov[rt<<1|1]==0) cov[rt<<1|1]=1;
 86         else if(cov[rt<<1|1]==1) cov[rt<<1|1]=0;
 87         else if(cov[rt<<1|1]==2) cov[rt<<1|1]=-1;
 88         else cov[rt<<1|1]=2;
 89         cov[rt]=-1;
 90     }
 91 }
 92 
 93 void updata(int L,int R,int op,int l,int r,int rt){
 94     if(L<=l&&r<=R){
 95         int len=r-l+1;
 96         if(op==0){
 97             lsum1[rt]=rsum1[rt]=msum1[rt]=num[rt]=0;
 98             lsum0[rt]=rsum0[rt]=msum0[rt]=len;
 99             cov[rt]=0;
100         }
101         else if(op==1){
102             lsum1[rt]=rsum1[rt]=msum1[rt]=num[rt]=len;
103             lsum0[rt]=rsum0[rt]=msum0[rt]=0;
104             cov[rt]=1;
105         }
106         else{
107             XOR(rt,len);
108             if(cov[rt]==0)      cov[rt]=1;
109             else if(cov[rt]==1) cov[rt]=0;
110             else if(cov[rt]==-1)cov[rt]=2;
111             else                cov[rt]=-1;
112         }
113         return ;
114     }
115     if(cov[rt]!=-1) pushDown(rt,r-l+1);
116     int m=(l+r)>>1;
117     if(R<=m) updata(L,R,op,lson);
118     else if(L>m) updata(L,R,op,rson);
119     else{
120         updata(L,R,op,lson);
121         updata(L,R,op,rson);
122     }
123     pushUp(rt,r-l+1);
124 }
125 
126 int query1(int L,int R,int l,int r,int rt){
127     if(L<=l&&r<=R) return num[rt];
128     if(cov[rt]!=-1) pushDown(rt,r-l+1);
129     int m=(l+r)>>1;
130     if(R<=m) return query1(L,R,lson);
131     else if(L>m) return query1(L,R,rson);
132     else return query1(L,R,lson)+query1(L,R,rson);
133 }
134 
135 int query2(int L,int R,int l,int r,int rt){
136     if(L<=l&&r<=R) return msum1[rt];
137     if(cov[rt]!=-1) pushDown(rt,r-l+1);
138     int m=(l+r)>>1;
139     if(R<=m) return query2(L,R,lson);
140     else if(L>m) return query2(L,R,rson);
141     else{
142         int ta=query2(L,R,lson);
143         int tb=query2(L,R,rson);
144         int temp=max(ta,tb);
145         int ans=min(m-L+1,rsum1[rt<<1])+min(R-m,lsum1[rt<<1|1]);
146         return max(ans,temp);
147     }    
148 }
149 
150 int main()
151 {
152     //freopen("in.txt","r",stdin);
153     int T,n,m,a,b,op;
154     scanf("%d",&T);
155     while(T--){
156         scanf("%d %d",&n,&m);
157         build(1,n,1);
158         while(m--){
159             scanf("%d %d %d",&op,&a,&b);
160             if(op<3) updata(a+1,b+1,op,1,n,1);
161             else if(op==3) printf("%d\n",query1(a+1,b+1,1,n,1));
162             else printf("%d\n",query2(a+1,b+1,1,n,1));
163         }
164     }
165     return 0;
166 }

 

 

 

 

 

posted on 2012-11-13 12:11  Acmer_Roney  阅读(228)  评论(0编辑  收藏  举报

导航