HDU 3397 Sequence operation

题目意思很简单,四种操作:全部变成1,全部变成0,或者区间异或,查询区间1的个数,和区间连续的1的最大长度。理解起来没有问题,可是写起代码来发现非常繁琐,共用了9个数组,差不多200行了,第一次写这么长得代码,WA一次,后来发现某个地方rt<<1,写成了rt<<1|1,还有PushUp向上更新时忘记了cover[rt]也要根据sum[rt]的值进行更新。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<cstdlib>
  5 #define N 111111
  6 #define lson l,m,rt<<1
  7 #define rson m+1,r,rt<<1|1
  8 using namespace std;
  9 
 10 int sum[N<<2],msum[N<<2],lsum[N<<2],rsum[N<<2],XOR[N<<2],cover[N<<2],msum0[N<<2],lsum0[N<<2],rsum0[N<<2];
 11 
 12 
 13 //sum表示区间1的个数,msum表示区间连续1的最大长度,lsum表示从左端开始的1的最大长度,
 14 //XOR为异或标记,cover为覆盖标记,1,0表示区间分别被1,0完全覆盖,-1不完全覆盖
 15 //msum0,lsum0,rsum0表示对应的0的个数的统计。
 16 
 17 
 18 void PushUp(int rt,int m)
 19 {
 20     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
 21     cover[rt]=((sum[rt]==m)?1:((sum[rt]==0)?0:-1));
 22     lsum[rt]=lsum[rt<<1];//我擦
 23     rsum[rt]=rsum[rt<<1|1];
 24     lsum0[rt]=lsum0[rt<<1];
 25     rsum0[rt]=rsum0[rt<<1|1];
 26     if(lsum[rt]==(m-(m>>1)))
 27         lsum[rt]+=lsum[rt<<1|1];
 28     else if(lsum0[rt]==(m-(m>>1)))
 29         lsum0[rt]+=lsum0[rt<<1|1];
 30     if(rsum[rt]==(m>>1))
 31         rsum[rt]+=rsum[rt<<1];
 32     else if(rsum0[rt]==(m>>1))
 33         rsum0[rt]+=rsum0[rt<<1];
 34     msum0[rt]=max(max(msum0[rt<<1],msum0[rt<<1|1]),rsum0[rt<<1]+lsum0[rt<<1|1]);
 35     msum[rt]=max(max(msum[rt<<1],msum[rt<<1|1]),rsum[rt<<1]+lsum[rt<<1|1]);
 36 }
 37 
 38 void FXOR(int rt,int m)
 39 {
 40     if(cover[rt]!=-1)
 41     {
 42         cover[rt]^=1;
 43         sum[rt]=msum[rt]=lsum[rt]=rsum[rt]=m*cover[rt];
 44         msum0[rt]=lsum0[rt]=rsum0[rt]=m*(1-cover[rt]);
 45     }
 46     else
 47     {
 48         XOR[rt]^=1;
 49         sum[rt]=(m-sum[rt]);
 50         int a=lsum[rt],b=rsum[rt];
 51         lsum[rt]=lsum0[rt];
 52         rsum[rt]=rsum0[rt];
 53         lsum0[rt]=a;
 54         rsum0[rt]=b;
 55         a=msum[rt];
 56         msum[rt]=msum0[rt];
 57         msum0[rt]=a;
 58     }
 59 }
 60 
 61 void PushDown(int rt,int m)
 62 {
 63     if(cover[rt]!=-1)
 64     {
 65         lsum[rt<<1]=rsum[rt<<1]=msum[rt<<1]=sum[rt<<1]=(m-(m>>1))*cover[rt];
 66         lsum[rt<<1|1]=rsum[rt<<1|1]=msum[rt<<1|1]=sum[rt<<1|1]=(m>>1)*cover[rt];
 67         lsum0[rt<<1]=rsum0[rt<<1]=msum0[rt<<1]=(m-(m>>1))*(1-cover[rt]);
 68         lsum0[rt<<1|1]=rsum0[rt<<1|1]=msum0[rt<<1|1]=(m>>1)*(1-cover[rt]);
 69         cover[rt<<1]=cover[rt<<1|1]=cover[rt];
 70         XOR[rt<<1]=XOR[rt<<1|1]=0;
 71         cover[rt]=-1;
 72     }
 73     if(XOR[rt])
 74     {
 75         FXOR(rt<<1,(m-(m>>1)));
 76         FXOR(rt<<1|1,(m>>1));
 77         XOR[rt]=0;
 78     }
 79 
 80 }
 81 
 82 void build(int l,int r,int rt)
 83 {
 84     XOR[rt]=0;
 85     if(l==r)
 86     {
 87         scanf("%d",&sum[rt]);
 88         lsum[rt]=rsum[rt]=msum[rt]=cover[rt]=sum[rt];
 89         lsum0[rt]=rsum0[rt]=msum0[rt]=1-sum[rt];
 90         return;
 91     }
 92     int m=(l+r)>>1;
 93     build(lson);
 94     build(rson);
 95     PushUp(rt,r-l+1);
 96 }
 97 
 98 void update(int L,int R,int c,int l,int r,int rt)
 99 {
100     if(L<=l&&R>=r)
101     {
102         if(c==0)
103             cover[rt]=0,lsum[rt]=rsum[rt]=sum[rt]=msum[rt]=0,lsum0[rt]=rsum0[rt]=msum0[rt]=r-l+1,XOR[rt]=0;
104         else if(c==1)
105             cover[rt]=1,lsum[rt]=rsum[rt]=sum[rt]=msum[rt]=r-l+1,lsum0[rt]=rsum0[rt]=msum0[rt]=0,XOR[rt]=0;
106         else FXOR(rt,r-l+1);
107         return;
108     }
109     int m=(l+r)>>1;
110     PushDown(rt,r-l+1);
111     if(L<=m)
112         update(L,R,c,lson);
113     if(R>m)
114         update(L,R,c,rson);
115     PushUp(rt,r-l+1);
116 }
117 
118 int query1(int L,int R,int l,int r,int rt)
119 {
120     if(L<=l&&R>=r)
121         return sum[rt];
122     int m=(l+r)>>1;
123     PushDown(rt,r-l+1);
124     int res=0;
125     if(L<=m)
126         res+=query1(L,R,lson);
127     if(R>m)
128         res+=query1(L,R,rson);
129     return res;
130 }
131 
132 int query2(int L,int R,int l,int r,int rt)
133 {
134     if(L<=l&&R>=r)
135         return msum[rt];
136     int m=(l+r)>>1;
137     PushDown(rt,r-l+1);
138     int ans=0;
139     if(R<=m)
140         ans=max(ans,query2(L,R,lson));
141     else if(L>m)
142         ans=max(ans,query2(L,R,rson));
143     else
144     {
145         ans=max(ans,query2(L,R,lson));
146         ans=max(ans,query2(L,R,rson));
147         int ll,rr;
148         ll=min(m-L+1,rsum[rt<<1]);
149         rr=min(R-m,lsum[rt<<1|1]);
150         ans=max(ans,ll+rr);
151     }
152     return ans;
153 }
154 
155 int main(void)
156 {
157     int tc,n,m;
158     int op,a,b,ans;
159     scanf("%d",&tc);
160     while(tc--)
161     {
162         scanf("%d%d",&n,&m);
163         build(1,n,1);
164         while(m--)
165         {
166             scanf("%d%d%d",&op,&a,&b);
167             switch(op)
168             {
169             case 0:
170             case 1:
171             case 2:
172                 update(a+1,b+1,op,1,n,1);
173                 break;
174             case 3:
175                 ans=query1(a+1,b+1,1,n,1);
176                 printf("%d
",ans);
177                 break;
178             case 4:
179                 ans=query2(a+1,b+1,1,n,1);
180                 printf("%d
",ans);
181                 break;
182             }
183         }
184     }
185     return 0;
186 }
原文地址:https://www.cnblogs.com/rootial/p/3255923.html