/* 1表示黑,0表示白, 0 a b 表示询问区间[a,b]中最长连续黑石子的数目 1 a b 表示翻转区间[a,b]内的黑白 */ #include <iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #include<ctime> #include<map> #include<vector> using namespace std; const int N=100009; int n,m; int a[N]; struct Node { int L,R,len;//区间 int flag;//flag为松弛标志 int num0,max0,left0,right0; int num1,max1,left1,right1; //num1区间黑色的数目 max1最长连续黑的数目 left1区间左侧连续黑的数目 }node[N*4]; int max(int x,int y) { return x>y?x:y; } void lazy(int i) { int tmp; int lt = 2*i,rt = 2*i+1; node[i].num0 = node[lt].num0+node[rt].num0; node[i].num1 = node[lt].num1+node[rt].num1; node[i].max0 =max( node[lt].max0,node[rt].max0); node[i].max0 = max(node[i].max0, node[lt].right0+ node[rt].left0); node[i].left0 = node[lt].left0; node[i].right0 = node[rt].right0; if(node[lt].left0 == node[lt].len)//如果左子区间全0,那么它的左边连续0的个数就是左子区间加上右子区间的左边0的个数,下同。。。 node[i].left0 += node[rt].left0; if(node[rt].right0 == node[rt].len) node[i].right0 += node[lt].right0; node[i].max1 =max( node[lt].max1,node[rt].max1); node[i].max1 = max(node[i].max1, node[lt].right1+ node[rt].left1); node[i].left1 = node[lt].left1; node[i].right1 = node[rt].right1; if(node[lt].left1 == node[lt].len) node[i].left1 += node[rt].left1; if(node[rt].right1 == node[rt].len) node[i].right1 += node[lt].right1; } void create(int t,int L,int R) { int mid=(L+R)>>1,tmp; node[t].L=L; node[t].R=R; node[t].len=R-L+1; if(L==R) { node[t].left0=node[t].right0=node[t].max0=node[t].num0=a[R]^1; node[t].left1=node[t].right1=node[t].max1=node[t].num1=a[R]; node[t].flag=0; return ; } create(t<<1,L,mid);create((t<<1)+1,mid+1,R); lazy(t); node[t].flag=0; } void down(int t)//将t释放至其子树 { swap(node[t<<1].max1,node[t<<1].max0); swap(node[t<<1].num0,node[t<<1].num1); swap(node[t<<1].left0,node[t<<1].left1); swap(node[t<<1].right0,node[t<<1].right1); swap(node[(t<<1)+1].max1,node[(t<<1)+1].max0); swap(node[(t<<1)+1].num0,node[(t<<1)+1].num1); swap(node[(t<<1)+1].left0,node[(t<<1)+1].left1); swap(node[(t<<1)+1].right0,node[(t<<1)+1].right1); if(node[t].L!=node[t].R) { node[t<<1].flag ^=1; node[(t<<1)+1].flag ^=1; } } void update(int t,int L,int R) //更新区间[L,R],使区间黑变白,白变黑 { int mid=(node[t].R+node[t].L)>>1,tmp; if(node[t].L==L&&node[t].R==R) { node[t].flag ^=1; swap(node[t].max1,node[t].max0); swap(node[t].num0,node[t].num1); swap(node[t].left0,node[t].left1); swap(node[t].right0,node[t].right1); return ; } if(node[t].flag)//向下松弛操作 { node[t].flag=0; down(t); } if(R<=mid) update(t<<1,L,R); else if(L>mid) update((t<<1)+1,L,R); else {update(t<<1,L,mid),update((t<<1)+1,mid+1,R);} lazy(t); } int query(int t,int L,int R) { int mid=(node[t].R+node[t].L)>>1,tmp; if(node[t].L==L&&node[t].R==R) { return node[t].max1; } if(node[t].flag)//向下松弛操作 { node[t].flag=0; down(t); } if(R<=mid)tmp=query(t<<1,L,R); else if(L>mid)tmp=query((t<<1)+1,L,R); else { tmp=max(query(t<<1,L,mid),query((t<<1)+1,mid+1,R));//三者的最大值 int tmp1=node[t<<1].right1>mid-L+1?mid-L+1:node[t<<1].right1; int tmp2=node[(t<<1)+1].left1>R-mid?R-mid:node[(t<<1)+1].left1; tmp=max(tmp,tmp1+tmp2);//合并后可能比单个大 } return tmp; } int main() { int op,L,R; while(scanf("%d",&n)!=EOF) { ; for(int i=1;i<=n;i++) scanf("%d",&a[i]); create(1,1,n); scanf("%d",&m); while(m--) { scanf("%d%d%d",&op,&L,&R); if(!op)cout<<query(1,L,R)<<endl; else update(1,L,R); } } }