Question: it is important to find the longest one in a certain interval.
#include<cstdio>#include<cstring>#define left l,m,x<<1#define right m+1,r,x<<1|1const int LMT=100004;int ox[LMT<<2],lsum[2][LMT<<2],msum[2][LMT<<2],rsum[2][LMT<<2];void init(void){ memset(msum,0,sizeof(msum)); memset(lsum,0,sizeof(lsum)); memset(rsum,0,sizeof(rsum)); memset(ox,0,sizeof(ox));}inline int max(int a,int b){ return a>b?a:b;}void swap(int &a,int &b){ int t=a; a=b; b=t;}void fox(int l,int r,int x){ ox[x]^=1; swap(lsum[0][x],lsum[1][x]); swap(rsum[0][x],rsum[1][x]); swap(msum[0][x],msum[1][x]);}void cut(int l,int r,int x){ int m=(l+r)>>1; if(ox[x]) { fox(right);fox(left); ox[x]=0; }}void pushup(int pos,int x,int len){ lsum[pos][x]=lsum[pos][x<<1]; rsum[pos][x]=rsum[pos][x<<1|1]; if(lsum[pos][x<<1]==len-(len>>1))lsum[pos][x]+=lsum[pos][x<<1|1]; if(rsum[pos][x<<1|1]==len>>1)rsum[pos][x]+=rsum[pos][x<<1]; msum[pos][x]=max(rsum[pos][x<<1]+lsum[pos][x<<1|1],max(msum[pos][x<<1],msum[pos][x<<1|1]));}void update(int L,int R,int l,int r,int x){ if(L<=l&&r<=R) { fox(l,r,x); return; } cut(l,r,x); int m=(l+r)>>1; if(L<=m)update(L,R,left); if(R>m)update(L,R,right); pushup(0,x,r-l+1); pushup(1,x,r-l+1);}void query(int *res,int L,int R,int l,int r,int x){ if(L<=l&&r<=R) { res[0]=lsum[1][x]; res[1]=msum[1][x]; res[2]=rsum[1][x]; return; } int resl[3],resr[3],m=(l+r)>>1,len=r-l+1; memset(resl,0,sizeof(resl)); memset(resr,0,sizeof(resr)); cut(l,r,x); if(L<=m)query(resl,L,R,left); if(R>m)query(resr,L,R,right); res[0]=resl[0];res[2]=resr[2]; if(resl[0]==len-(len>>1))res[0]+=resr[0]; if(resr[2]==len>>1)res[2]+=resl[2]; res[1]=max(resl[2]+resr[0],max(resl[1],resr[1]));}void build(int l,int r,int x){ if(l==r) { int num; scanf("%d",&num); msum[1][x]=lsum[1][x]=rsum[1][x]=num; lsum[0][x]=msum[0][x]=rsum[0][x]=(num==0); return; } int m=(l+r)>>1; build(left); build(right); pushup(0,x,r-l+1); pushup(1,x,r-l+1);}int main(void){ int n,m,op,l,r,have[3]; while(~scanf("%d",&n)) { init(); build(0,n-1,1); scanf("%d",&m); while(m--) { scanf("%d%d%d",&op,&l,&r); l--;r--; if(op)update(l,r,0,n-1,1); else { memset(have,0,sizeof(have)); query(have,l,r,0,n-1,1); printf("%d\n",have[1]); } } } return 0;}