http://acm.hdu.edu.cn/showproblem.php?pid=3397
空间要开大点不然就RE。更新比较复杂,在取反时要注意先向下更新。
如这样的数据:
1
10 10
0 0 0 1 1 0 1 0 1 1
2 0 9
2 0 9
4 0 2
1 0 9
2 0 8
4 0 2
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #define lson l,mid,i<<1 5 #define rson mid+1,r,i<<1|1 6 using namespace std; 7 const int Ni = 100100; 8 int n; 9 struct node { 10 int sum1,sum0; 11 int mx1,lm1,rm1; 12 int mx0,lm0,rm0; 13 int lnum,rnum; 14 }tree[Ni<<3]; 15 int color[Ni<<3]; 16 inline void changes(int i) 17 { 18 swap(tree[i].mx1,tree[i].mx0); 19 swap(tree[i].sum1,tree[i].sum0); 20 swap(tree[i].lm1,tree[i].lm0); 21 swap(tree[i].rm1,tree[i].rm0); 22 tree[i].lnum=!tree[i].lnum; 23 tree[i].rnum=!tree[i].rnum; 24 } 25 inline void pushup(int l,int r,int i) 26 { 27 tree[i].mx1=max(tree[i<<1].mx1,tree[i<<1|1].mx1);///111111 28 if(tree[i<<1].rnum==1&&tree[i<<1|1].lnum==1) 29 { 30 tree[i].mx1=max(tree[i].mx1,tree[i<<1].rm1+tree[i<<1|1].lm1); 31 } 32 int mid=(l+r)>>1; 33 if(tree[i<<1].mx1==mid-l+1&&tree[i<<1].rnum==1&&tree[i<<1|1].lnum==1) 34 tree[i].lm1=tree[i<<1].mx1+tree[i<<1|1].lm1; 35 else 36 tree[i].lm1=tree[i<<1].lm1; 37 38 if(tree[i<<1|1].mx1==r-mid&&tree[i<<1].rnum==1&&tree[i<<1|1].lnum==1) 39 tree[i].rm1=tree[i<<1|1].mx1+tree[i<<1].rm1; 40 else 41 tree[i].rm1=tree[i<<1|1].rm1; 42 tree[i].lnum=tree[i<<1].lnum; 43 tree[i].rnum=tree[i<<1|1].rnum; 44 tree[i].sum1=tree[i<<1].sum1+tree[i<<1|1].sum1; 45 46 tree[i].mx0=max(tree[i<<1].mx0,tree[i<<1|1].mx0);///000000 47 if(tree[i<<1].rnum==0&&tree[i<<1|1].lnum==0) 48 { 49 tree[i].mx0=max(tree[i].mx0,tree[i<<1].rm0+tree[i<<1|1].lm0); 50 } 51 mid=(l+r)>>1; 52 if(tree[i<<1].mx0==mid-l+1&&tree[i<<1].rnum==0&&tree[i<<1|1].lnum==0) 53 tree[i].lm0=tree[i<<1].mx0+tree[i<<1|1].lm0; 54 else 55 tree[i].lm0=tree[i<<1].lm0; 56 57 if(tree[i<<1|1].mx0==r-mid&&tree[i<<1].rnum==0&&tree[i<<1|1].lnum==0) 58 tree[i].rm0=tree[i<<1|1].mx0+tree[i<<1].rm0; 59 else 60 tree[i].rm0=tree[i<<1|1].rm0; 61 tree[i].lnum=tree[i<<1].lnum; 62 tree[i].rnum=tree[i<<1|1].rnum; 63 tree[i].sum0=tree[i<<1].sum0+tree[i<<1|1].sum0; 64 } 65 inline void pushdown(int l,int r,int i) 66 { 67 if(color[i]==-8) return; 68 if(color[i]==1) 69 { 70 color[i<<1]=color[i<<1|1]=1; 71 color[i]=-8; 72 int mid=(l+r)>>1; 73 tree[i<<1].mx1=tree[i<<1].sum1=mid-l+1; 74 tree[i<<1].lm1=tree[i<<1].rm1=mid-l+1; 75 tree[i<<1].mx0=tree[i<<1].sum0=0; 76 tree[i<<1].lm0=tree[i<<1].rm0=0; 77 tree[i<<1].lnum=tree[i<<1].rnum=1; 78 79 tree[i<<1|1].mx1=tree[i<<1|1].sum1=r-mid; 80 tree[i<<1|1].lm1=tree[i<<1|1].rm1=r-mid; 81 tree[i<<1|1].mx0=tree[i<<1|1].sum0=0; 82 tree[i<<1|1].lm0=tree[i<<1|1].rm0=0; 83 tree[i<<1|1].lnum=tree[i<<1|1].rnum=1; 84 }else if(color[i]==0) 85 { 86 color[i<<1]=color[i<<1|1]=0; 87 color[i]=-8; 88 int mid=(l+r)>>1; 89 tree[i<<1].mx1=tree[i<<1].sum1=0; 90 tree[i<<1].lm1=tree[i<<1].rm1=0; 91 tree[i<<1].mx0=tree[i<<1].sum0=mid-l+1; 92 tree[i<<1].lm0=tree[i<<1].rm0=mid-l+1; 93 tree[i<<1].lnum=tree[i<<1].rnum=0; 94 95 tree[i<<1|1].mx1=tree[i<<1|1].sum1=0; 96 tree[i<<1|1].lm1=tree[i<<1|1].rm1=0; 97 tree[i<<1|1].mx0=tree[i<<1|1].sum0=r-mid; 98 tree[i<<1|1].lm0=tree[i<<1|1].rm0=r-mid; 99 tree[i<<1|1].lnum=tree[i<<1|1].rnum=0; 100 }else if(color[i]==2) 101 { 102 if(l<r){ 103 int mid=(l+r)>>1; 104 pushdown(l,mid,i<<1); 105 pushdown(mid+1,r,i<<1|1); 106 } 107 color[i<<1]=color[i<<1|1]=2; 108 color[i]=-8; 109 changes(i<<1); 110 changes(i<<1|1); 111 } 112 } 113 void build(int l=1,int r=n,int i=1) 114 { 115 color[i]=-8; 116 if(l==r) 117 { 118 int num; 119 scanf("%d",&num); 120 tree[i].lnum=tree[i].rnum=num; 121 122 tree[i].sum1=tree[i].mx1=num; 123 tree[i].lm1=tree[i].rm1=num; 124 125 tree[i].sum0=tree[i].mx0=!num; 126 tree[i].lm0=tree[i].rm0=!num; 127 return; 128 } 129 int mid=(l+r)>>1; 130 build(lson); 131 build(rson); 132 pushup(l,r,i); 133 } 134 int query(int ql,int qr,int flg,int l=1,int r=n,int i=1) 135 { 136 int ans=0; 137 if(flg==4) 138 { 139 int lsum=0,rsum=0; 140 if(ql<=l&&r<=qr) return tree[i].mx1; 141 int mid=(l+r)>>1; 142 pushdown(l,r,i); 143 if(tree[i<<1].rnum==1&&tree[i<<1|1].lnum==1) 144 { 145 int lsum,rsum; 146 lsum=min(mid-ql+1,tree[i<<1].rm1); 147 rsum=min(qr-mid,tree[i<<1|1].lm1); 148 ans=lsum+rsum; 149 } 150 if(ql<=mid) lsum=query(ql,qr,flg,lson); 151 if(qr>mid) rsum=query(ql,qr,flg,rson); 152 ans=max(ans,lsum); 153 ans=max(ans,rsum); 154 } 155 else 156 { 157 if(ql<=l&&r<=qr) return tree[i].sum1; 158 int mid=(l+r)>>1; 159 pushdown(l,r,i); 160 if(ql<=mid) ans+=query(ql,qr,flg,lson); 161 if(qr>mid) ans+=query(ql,qr,flg,rson); 162 } 163 return ans; 164 } 165 void update(int ql,int qr,int num,int l=1,int r=n,int i=1) 166 { 167 if(ql<=l&&r<=qr) 168 { 169 if(num==1) 170 { 171 tree[i].mx1=tree[i].sum1=(r-l+1); 172 tree[i].lm1=tree[i].rm1=(r-l+1); 173 174 tree[i].mx0=tree[i].sum0=0; 175 tree[i].lm0=tree[i].rm0=0; 176 177 tree[i].lnum=tree[i].rnum=num; 178 color[i]=num; 179 } 180 else if(num==0) 181 { 182 tree[i].mx1=tree[i].sum1=0; 183 tree[i].lm1=tree[i].rm1=0; 184 185 tree[i].mx0=tree[i].sum0=(r-l+1); 186 tree[i].lm0=tree[i].rm0=(r-l+1); 187 188 tree[i].lnum=tree[i].rnum=num; 189 color[i]=num; 190 } 191 else if(num==2) 192 { 193 if(color[i]==2) 194 { 195 color[i]=-8; 196 } 197 else 198 { 199 if(l<r) 200 pushdown(l,r,i); 201 color[i]=2; 202 } 203 changes(i); 204 } 205 return; 206 } 207 pushdown(l,r,i); 208 int mid=(l+r)>>1; 209 if(ql<=mid) update(ql,qr,num,lson); 210 if(qr>mid) update(ql,qr,num,rson); 211 pushup(l,r,i); 212 } 213 int main() 214 { 215 int m,i,t,l,r,f; 216 cin>>t; 217 while(t--) 218 { 219 scanf("%d%d",&n,&m); 220 build(); 221 for(i=0;i<m;i++) 222 { 223 scanf("%d%d%d",&f,&l,&r); 224 l++;r++; 225 if(f<3) 226 { 227 update(l,r,f); 228 } 229 else 230 { 231 int ans=query(l,r,f); 232 printf("%d\n",ans); 233 } 234 } 235 } 236 return 0; 237 }