思路:
线段树结构更新维护,结构内部包括 1的最大左连续、最大右连续、最大连续长度,0的最大左连续、最大右连续、最大连续长度,1的个数、覆盖值、取反,一共9个值,其中的取反操作要特别注意,其余的看代码吧。。
如果代码看不懂的话,建议先做一下区间最大连续和、还有poj 3225.
View Code
1 #include<iostream> 2 #include<stdio.h> 3 using namespace std; 4 const int N = 100003; 5 struct node 6 { 7 int lo,ro,mo; 8 int lz,rz,mz; 9 int oc,cover,re; 10 int len; 11 }tree[N<<2]; 12 int Max(int a,int b) 13 { 14 return a>b?a:b; 15 } 16 void Get_Re(int t) 17 { 18 if(tree[t].cover!=-1)tree[t].cover^=1; 19 else tree[t].re^=1; 20 } 21 void PushDown(int t,int m) 22 { 23 if(tree[t].cover!=-1) 24 { 25 int t1=t<<1; 26 int t2=t1|1; 27 int ll=m-(m>>1),rr=(m>>1); 28 tree[t1].cover=tree[t2].cover=tree[t].cover; 29 tree[t1].re=tree[t2].re=0; 30 tree[t1].lo=tree[t1].ro=tree[t1].mo=(tree[t].cover?ll:0); 31 tree[t1].lz=tree[t1].rz=tree[t1].mz=(tree[t].cover?0:ll); 32 tree[t2].lo=tree[t2].ro=tree[t2].mo=(tree[t].cover?rr:0); 33 tree[t2].lz=tree[t2].rz=tree[t2].mz=(tree[t].cover?0:rr); 34 tree[t1].oc=(tree[t].cover?ll:0); 35 tree[t2].oc=(tree[t].cover?rr:0); 36 tree[t].cover=-1; 37 } 38 if(tree[t].re) 39 { 40 int t1=t<<1; 41 int t2=t1|1; 42 int ll=m-(m>>1),rr=(m>>1); 43 Get_Re(t1);Get_Re(t2); 44 swap(tree[t1].lo,tree[t1].lz);swap(tree[t1].ro,tree[t1].rz);swap(tree[t1].mo,tree[t1].mz); 45 tree[t1].oc=ll-tree[t1].oc; 46 swap(tree[t2].lo,tree[t2].lz);swap(tree[t2].ro,tree[t2].rz);swap(tree[t2].mo,tree[t2].mz); 47 tree[t2].oc=rr-tree[t2].oc; 48 tree[t].re=0; 49 } 50 } 51 void PushUp(int t,int m) 52 { 53 int t1=t<<1; 54 int t2=t1|1; 55 int ll=m-(m>>1),rr=m>>1; 56 tree[t].oc=tree[t1].oc+tree[t2].oc; 57 58 tree[t].lo=tree[t1].lo; 59 if(tree[t].lo==ll)tree[t].lo+=tree[t2].lo; 60 tree[t].ro=tree[t2].ro; 61 if(tree[t].ro==rr)tree[t].ro+=tree[t1].ro; 62 tree[t].mo=Max(tree[t1].ro+tree[t2].lo,Max(tree[t1].mo,tree[t2].mo)); 63 64 tree[t].lz=tree[t1].lz; 65 if(tree[t].lz==ll)tree[t].lz+=tree[t2].lz; 66 tree[t].rz=tree[t2].rz; 67 if(tree[t].rz==rr)tree[t].rz+=tree[t1].rz; 68 tree[t].mz=Max(tree[t1].rz+tree[t2].lz,Max(tree[t1].mz,tree[t2].mz)); 69 } 70 void build(int t,int l,int r) 71 { 72 tree[t].re=0; 73 tree[t].cover=-1; 74 tree[t].len=(r-l+1); 75 if(l==r) 76 { 77 scanf("%d",&tree[t].oc); 78 tree[t].lo=tree[t].ro=tree[t].mo=(tree[t].oc); 79 tree[t].lz=tree[t].rz=tree[t].mz=(tree[t].oc?0:1); 80 return ; 81 } 82 int m=(l+r)>>1; 83 build(t<<1,l,m); 84 build(t<<1|1,m+1,r); 85 PushUp(t,r-l+1); 86 } 87 void update(int t,int l,int r,int L,int R,int o,int val) 88 { 89 if(L<=l&&r<=R) 90 { 91 if(o==2) 92 { 93 Get_Re(t); 94 tree[t].oc=(r-l+1)-tree[t].oc; 95 swap(tree[t].lo,tree[t].lz);swap(tree[t].ro,tree[t].rz);swap(tree[t].mo,tree[t].mz); 96 } 97 else 98 { 99 tree[t].lo=tree[t].ro=tree[t].mo=(val?r-l+1:0); 100 tree[t].lz=tree[t].rz=tree[t].mz=(val?0:r-l+1); 101 tree[t].oc=(val?(r-l+1):0); 102 tree[t].cover=val; 103 tree[t].re=0; 104 } 105 return ; 106 } 107 PushDown(t,r-l+1); 108 int m=(l+r)>>1; 109 if(L<=m)update(t<<1,l,m,L,R,o,val); 110 if(R>m)update(t<<1|1,m+1,r,L,R,o,val); 111 PushUp(t,r-l+1); 112 } 113 int query1(int t,int l,int r,int L,int R) 114 { 115 if(L<=l&&r<=R)return tree[t].oc; 116 if(l==r)return 0; 117 PushDown(t,r-l+1); 118 int m=(l+r)>>1; 119 int answer=0; 120 if(L<=m)answer+=query1(t<<1,l,m,L,R); 121 if(R>m)answer+=query1(t<<1|1,m+1,r,L,R); 122 return answer; 123 } 124 node query2(int t,int l,int r,int L,int R) 125 { 126 node temp={0}; 127 if(L<=l&&r<=R)return tree[t]; 128 if(l==r)return tree[t]; 129 PushDown(t,r-l+1); 130 int m=(l+r)>>1; 131 node t1,t2; 132 int flag1=0,flag2=0; 133 if(L<=m){t1=query2(t<<1,l,m,L,R);flag1=1;} 134 if(R>m){t2=query2(t<<1|1,m+1,r,L,R);flag2=1;} 135 if(flag1&&flag2) 136 { 137 temp.len=t1.len+t2.len; 138 temp.lo=t1.lo; 139 if(temp.lo==t1.len)temp.lo+=t2.lo; 140 temp.ro=t2.ro; 141 if(temp.ro==t2.len)temp.ro+=t1.ro; 142 temp.mo=Max(t1.ro+t2.lo,Max(t1.mo,t2.mo)); 143 return temp; 144 } 145 else 146 if(flag1)return t1; 147 else return t2; 148 } 149 int main() 150 { 151 // freopen("in.txt","r",stdin); 152 // freopen("out2.txt","w",stdout); 153 int Case,n,m,o,a,b; 154 scanf("%d",&Case); 155 while(Case--) 156 { 157 scanf("%d%d",&n,&m); 158 n--; 159 build(1,0,n); 160 while (m--) 161 { 162 scanf("%d%d%d",&o,&a,&b); 163 if(o<=2) 164 update(1,0,n,a,b,o,o); 165 else 166 { 167 if(o==3)printf("%d\n",query1(1,0,n,a,b)); 168 else 169 { 170 node temp=query2(1,0,n,a,b); 171 printf("%d\n",temp.mo); 172 } 173 } 174 } 175 } 176 return 0; 177 }