调了很久也不知道错在哪里
先留着有空对拍看看
/* ???????????:??set,??rev,????0,????0,????1,????1,????0,????1,??0??,??1?? ??????????????,??????? ??flag???rev */ #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; #define maxn 100005 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 int flag[maxn<<2],rev[maxn<<2]; int lmx0[maxn<<2],rmx0[maxn<<2],lmx1[maxn<<2],rmx1[maxn<<2]; int mx0[maxn<<2],mx1[maxn<<2],num0[maxn<<2],num1[maxn<<2]; inline void pushup(int rt,int l,int r){ num0[rt]=num0[rt<<1]+num0[rt<<1|1]; num1[rt]=num1[rt<<1]+num1[rt<<1|1]; int m=l+r>>1; lmx0[rt]=lmx0[rt<<1];rmx0[rt]=rmx0[rt<<1|1]; mx0[rt]=(max(mx0[rt<<1],mx0[rt<<1|1]),rmx0[rt<<1]+lmx0[rt<<1|1]); if(m-l+1==lmx0[rt<<1]) lmx0[rt]=m-l+1+lmx0[rt<<1|1]; if(r-m==rmx0[rt<<1|1]) rmx0[rt]=r-m+rmx0[rt<<1]; lmx1[rt]=lmx1[rt<<1];rmx1[rt]=rmx1[rt<<1|1]; mx1[rt]=(max(mx1[rt<<1],mx1[rt<<1|1]),rmx1[rt<<1]+lmx1[rt<<1|1]); if(m-l+1==lmx1[rt<<1]) lmx1[rt]=m-l+1+lmx1[rt<<1|1]; if(r-m==rmx1[rt<<1|1]) rmx1[rt]=r-m+rmx1[rt<<1]; /*if(rmx0[rt<<1] && lmx0[rt<<1|1]) {//????????1,?????????0 if(m-l+1==lmx0[rt<<1]) lmx0[rt]=m-l+1+lmx0[rt<<1|1]; if(r-m==rmx0[rt<<1|1]) rmx0[rt]=r-m+rmx0[rt<<1]; mx0[rt]=max(mx0[rt],rmx0[rt<<1]+lmx0[rt<<1|1]); } mx0[rt]=max(mx0[rt],max(lmx0[rt],rmx0[rt])); lmx1[rt]=lmx1[rt<<1];rmx1[rt]=rmx1[rt<<1|1]; mx1[rt]=max(mx1[rt<<1],mx1[rt<<1|1]); if(rmx1[rt<<1] && lmx1[rt<<1|1]) {//???????1,????????1 if(m-l+1==lmx1[rt<<1]) lmx1[rt]=m-l+1+lmx1[rt<<1|1]; if(r-m==rmx1[rt<<1|1]) rmx1[rt]=r-m+rmx1[rt<<1]; mx1[rt]=max(mx1[rt],rmx1[rt<<1]+lmx1[rt<<1|1]); } mx1[rt]=max(mx1[rt],max(lmx1[rt],rmx1[rt]));*/ } void build(int l,int r,int rt){ flag[rt]=-1;rev[rt]=0; if(l==r){ int tmp; scanf("%d",&tmp); if(tmp){ lmx1[rt]=rmx1[rt]=mx1[rt]=num1[rt]=mx1[rt]=1; lmx0[rt]=rmx0[rt]=mx0[rt]=num0[rt]=mx0[rt]=0; } else { lmx1[rt]=rmx1[rt]=mx1[rt]=num1[rt]=mx1[rt]=0; lmx0[rt]=rmx0[rt]=mx0[rt]=num0[rt]=mx0[rt]=1; } return; } int m=l+r>>1; build(lson); build(rson); pushup(rt,l,r); } inline void set0(int rt,int l,int r){ lmx0[rt]=rmx0[rt]=mx0[rt]=num0[rt]=r-l+1; rev[rt]=lmx1[rt]=rmx1[rt]=mx1[rt]=num1[rt]=0; flag[rt]=0;rev[rt]=0; } inline void set1(int rt,int l,int r){ rev[rt]=lmx0[rt]=rmx0[rt]=mx0[rt]=num0[rt]=0; lmx1[rt]=rmx1[rt]=mx1[rt]=num1[rt]=r-l+1; flag[rt]=1;rev[rt]=0; } inline void rever(int rt,int l,int r){ swap(lmx0[rt],lmx1[rt]); swap(rmx0[rt],rmx1[rt]); swap(mx0[rt],mx1[rt]); swap(num0[rt],num1[rt]); rev[rt]^=1; } inline void pushdown(int rt,int l,int r){ int m=l+r>>1; if(flag[rt]!=-1){ if(flag[rt]==0){ set0(rt<<1,l,m); set0(rt<<1|1,m+1,r); } if(flag[rt]==1) { set1(rt<<1,l,m); set1(rt<<1|1,m+1,r); } flag[rt]=-1; } if(rev[rt]){ rever(rt<<1,l,m); rever(rt<<1|1,m+1,r); rev[rt]=0; } } void update(int L,int R,int op,int l,int r,int rt){ if(L<=l && R>=r){ if(op==2) rever(rt,l,r); else if(op==0) set0(rt,l,r); else if(op==1) set1(rt,l,r); return; } pushdown(rt,l,r);//??flag,rev?????? int m=l+r>>1; if(L<=m) update(L,R,op,lson); if(R>m) update(L,R,op,rson); pushup(rt,l,r); } int query(int L,int R,int op,int l,int r,int rt){ if(L<=l && R>=r){ if(op==3) return num1[rt]; else return mx1[rt]; } int m=l+r>>1; pushdown(rt,l,r); int res=0; if(R<=m) res=query(L,R,op,lson); else if(L>m) res=query(L,R,op,rson); else { int temp1=query(L,R,op,lson);//????? int temp2=query(L,R,op,rson);//????? if(op==3) res=temp1+temp2;//???????????1,???????????? else{ int temp3,temp4; temp3=min(m-L+1,rmx1[rt<<1]); temp4=min(R-m,lmx1[rt<<1|1]); res=max(temp3+temp4,max(temp1,temp2)); } } pushup(rt,l,r); return res; } int main(){ int T,n,q,a,b,op; cin >> T; while(T--){ scanf("%d%d",&n,&q); build(0,n-1,1); while(q--){ scanf("%d%d%d",&op,&a,&b); if(op<=2) update(a,b,op,0,n-1,1); else printf("%d\n",query(a,b,op,0,n-1,1)); } } return 0; }