标签:
对于30%的数据,1<=n, m<=1000
对于100%的数据,1<=n, m<=100000
题解:
其实是蛮简单的一道题(不说了,我交了不下10次。。)
我们需要在维护一些关于0的量,对于2这个操作,其实就是交换0和1的量。。。
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> using namespace std; #define p1 (p<<1) #define p2 (p<<1|1) int n,m,i,p,x,y; int a[100005],t[400005],tl[400005]; int tmid[400005],tr[400005],add[400005]; int T[400005],Tmid[400005],Tr[400005],Tl[400005]; int ans[15]; void build(int l,int r,int p) { if(l==r) { add[p]=a[l]; tmid[p]=tl[p]=tr[p]=t[p]=a[l]; Tmid[p]=Tl[p]=Tr[p]=T[p]=1-a[l]; return; } int mid=(l+r)>>1; build(l,mid,p1); build(mid+1,r,p2); t[p]=t[p1]+t[p2]; if(t[p1]==mid-l+1) tl[p]=tl[p1]+tl[p2];else tl[p]=tl[p1]; if(t[p2]==r-mid) tr[p]=tr[p2]+tr[p1];else tr[p]=tr[p2]; tmid[p]=max(tmid[p1],tmid[p2]); tmid[p]=max(tmid[p],tr[p1]+tl[p2]); T[p]=T[p1]+T[p2]; if(T[p1]==mid-l+1) Tl[p]=Tl[p1]+Tl[p2];else Tl[p]=Tl[p1]; if(T[p2]==r-mid) Tr[p]=Tr[p2]+Tr[p1];else Tr[p]=Tr[p2]; Tmid[p]=max(Tmid[p1],Tmid[p2]); Tmid[p]=max(Tmid[p],Tr[p1]+Tl[p2]); } void update(int l,int r,int x,int y,int z,int p) { if(x<=l&&r<=y) { if(z==0) { add[p]=0; T[p]=Tmid[p]=Tr[p]=Tl[p]=r-l+1; t[p]=tmid[p]=tr[p]=tl[p]=0; } else if(z==1) { add[p]=1; T[p]=Tmid[p]=Tr[p]=Tl[p]=0; t[p]=tmid[p]=tr[p]=tl[p]=r-l+1; } else if(z==2) { swap(t[p],T[p]); swap(tl[p],Tl[p]); swap(tr[p],Tr[p]); swap(tmid[p],Tmid[p]); add[p]=1-add[p]; } return; } int mid=(l+r)>>1; if(add[p]!=-1) { update(l,mid,l,mid,add[p],p1); update(mid+1,r,mid+1,r,add[p],p2); add[p]=-1; } if(x<=mid) update(l,mid,x,y,z,p1); if(y>mid) update(mid+1,r,x,y,z,p2); t[p]=t[p1]+t[p2]; if(t[p1]==mid-l+1) tl[p]=tl[p1]+tl[p2];else tl[p]=tl[p1]; if(t[p2]==r-mid) tr[p]=tr[p2]+tr[p1];else tr[p]=tr[p2]; tmid[p]=max(tmid[p1],tmid[p2]); tmid[p]=max(tmid[p],tr[p1]+tl[p2]); T[p]=T[p1]+T[p2]; if(T[p1]==mid-l+1) Tl[p]=Tl[p1]+Tl[p2];else Tl[p]=Tl[p1]; if(T[p2]==r-mid) Tr[p]=Tr[p2]+Tr[p1];else Tr[p]=Tr[p2]; Tmid[p]=max(Tmid[p1],Tmid[p2]); Tmid[p]=max(Tmid[p],Tr[p1]+Tl[p2]); } void solve(int l,int r,int x,int y,int p,int X) { if(x==l&&y==r) { ans[3]=max(ans[3],ans[4]+tl[p]); if(ans[1]==l-X) ans[2]+=tl[p]; if(t[p]==r-l+1) ans[4]+=tr[p];else ans[4]=tr[p]; ans[3]=max(ans[3],tmid[p]); ans[1]+=t[p]; return; } int mid=(l+r)>>1; if(add[p]!=-1) { update(l,mid,l,mid,add[p],p1); update(mid+1,r,mid+1,r,add[p],p2); add[p]=-1; } if(y<=mid) solve(l,mid,x,y,p1,X);else if(x>mid) solve(mid+1,r,x,y,p2,X);else { solve(l,mid,x,mid,p1,X); solve(mid+1,r,mid+1,y,p2,X); } t[p]=t[p1]+t[p2]; if(t[p1]==mid-l+1) tl[p]=tl[p1]+tl[p2];else tl[p]=tl[p1]; if(t[p2]==r-mid) tr[p]=tr[p2]+tr[p1];else tr[p]=tr[p2]; tmid[p]=max(tmid[p1],tmid[p2]); tmid[p]=max(tmid[p],tr[p1]+tl[p2]); T[p]=T[p1]+T[p2]; if(T[p1]==mid-l+1) Tl[p]=Tl[p1]+Tl[p2];else Tl[p]=Tl[p1]; if(T[p2]==r-mid) Tr[p]=Tr[p2]+Tr[p1];else Tr[p]=Tr[p2]; Tmid[p]=max(Tmid[p1],Tmid[p2]); Tmid[p]=max(Tmid[p],Tr[p1]+Tl[p2]); } int main() { scanf("%d%d",&n,&m); for(i=1;i<=n;i++) scanf("%d",&a[i]); memset(add,-1,sizeof(add)); build(1,n,1); for(i=1;i<=m;i++) { scanf("%d%d%d",&p,&x,&y); x++;y++; if(p<=2) { update(1,n,x,y,p,1); } else { memset(ans,0,sizeof(ans)); solve(1,n,x,y,1,x); if(p==3) printf("%d\n",ans[1]);else printf("%d\n",ans[3]); } } return 0; }
标签:
原文地址:http://www.cnblogs.com/lwq12138/p/5447417.html