Description
lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[a,b]区间内的所有数全部取反,也就是说把所有的0变成1,把所有的1变成0 3 a b 询问[a, b]区间内总共有多少个1 4 a b 询问[a, b]区间内最多有多少个连续的1 对于每一种询问操作,lxhgww都需要给出回答,聪明的程序员们,你们能帮助他吗?
坑爹的线段树。。
对于每个区间,维护:
左右连续串的长度,记录左右两边是0还是1;
记录区间内最长的连续的0,和1的数;
写起来太麻烦,调了一天ORZ;
/************************************************************** Problem: 1858 User: 1115825064 Language: C++ Result: Accepted Time:1696 ms Memory:22468 kb ****************************************************************/ #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=100010; int m,n; struct tr{ int lz,rz,l,r,sum,sum1,sum0; bool ll,rr,la[2],lqf; }t[N*6]; bool AA[N]; void fg(int ,int ,int ,int ); void qf(int ,int ,int ); void build(int wz,int l,int r) { t[wz].l=l; t[wz].r=r; if(l==r) { t[wz].lz=1; t[wz].rz=1; t[wz].ll=AA[l]; t[wz].rr=AA[l]; t[wz].sum1=int(AA[l]); t[wz].sum=t[wz].sum1; t[wz].sum0=!t[wz].sum1; return ; } int mid=(r+l)/2; build(wz<<1,l,mid); build((wz<<1)+1,mid+1,r); t[wz].sum=t[wz*2].sum+t[wz*2+1].sum; if(t[wz*2].lz==mid-l+1) { t[wz].lz=mid-l+1; if(t[wz*2].ll==t[wz*2+1].ll) t[wz].lz+=t[wz*2+1].lz; } else t[wz].lz=t[wz*2].lz; t[wz].ll=t[wz*2].ll; if(t[wz*2+1].rz==r-mid) { t[wz].rz=r-mid; if(t[wz*2+1].rr==t[wz*2].rr) t[wz].rz+=t[wz*2].rz; } else t[wz].rz=t[wz*2+1].rz; t[wz].rr=t[wz*2+1].rr; t[wz].sum1=max(t[wz*2].sum1,t[wz*2+1].sum1); if(t[wz*2].rr&&t[wz*2+1].ll&&t[wz*2].rz+t[wz*2+1].lz>t[wz].sum1) t[wz].sum1=t[wz*2].rz+t[wz*2+1].lz; t[wz].sum0=max(t[wz*2].sum0,t[wz*2+1].sum0); if(!t[wz*2].rr&&!t[wz*2+1].ll&&t[wz*2].rz+t[wz*2+1].lz>t[wz].sum0) t[wz].sum0=t[wz*2].rz+t[wz*2+1].lz; return ; } void fg(int p,int wz,int l,int r) { if(t[wz].l==0||t[wz].r==0) return ; if(t[wz].l>=l&&t[wz].r<=r) { t[wz].la[p]=1,t[wz].la[!p]=0,t[wz].lqf=0; t[wz].ll=p; t[wz].rr=p; t[wz].rz=(t[wz].r-t[wz].l+1); t[wz].lz=t[wz].rz; t[wz].sum1=p==1?t[wz].lz:0; t[wz].sum=t[wz].sum1; t[wz].sum0=t[wz].lz-t[wz].sum1; } else { if(t[wz].la[0]) fg(0,wz*2,1,n),fg(0,wz*2+1,1,n); if(t[wz].la[1]) fg(1,wz*2+1,1,n),fg(1,wz*2,1,n); if(t[wz].lqf) qf(wz*2,1,n),qf(wz*2+1,1,n); t[wz].lqf=0; t[wz].la[0]=0; t[wz].la[1]=0; if(t[wz*2].r>=l) fg(p,wz*2,l,r); if(t[wz*2+1].l<=r) fg(p,wz*2+1,l,r); t[wz].sum=t[wz*2].sum+t[wz*2+1].sum; int mid=(t[wz].l+t[wz].r)/2; if(t[wz*2].lz==mid-t[wz].l+1) { t[wz].lz=mid-t[wz].l+1; if(t[wz*2].ll==t[wz*2+1].ll) t[wz].lz+=t[wz*2+1].lz; } else t[wz].lz=t[wz*2].lz; t[wz].ll=t[wz*2].ll; if(t[wz*2+1].rz==t[wz].r-mid) { t[wz].rz=t[wz].r-mid; if(t[wz*2+1].rr==t[wz*2].rr) t[wz].rz+=t[wz*2].rz; } else t[wz].rz=t[wz*2+1].rz; t[wz].rr=t[wz*2+1].rr; t[wz].sum1=max(t[wz*2].sum1,t[wz*2+1].sum1); if(t[wz*2].rr&&t[wz*2+1].ll&&t[wz*2].rz+t[wz*2+1].lz>t[wz].sum1) t[wz].sum1=t[wz*2].rz+t[wz*2+1].lz; t[wz].sum0=max(t[wz*2].sum0,t[wz*2+1].sum0); if(!t[wz*2].rr&&!t[wz*2+1].ll&&t[wz*2].rz+t[wz*2+1].lz>t[wz].sum0) t[wz].sum0=t[wz*2].rz+t[wz*2+1].lz; } } void qf(int wz,int l,int r) { if(t[wz].l==0||t[wz].r==0) return ; if(t[wz].l>=l&&t[wz].r<=r) { t[wz].ll=!t[wz].ll; t[wz].rr=!t[wz].rr; if(t[wz].la[0]) t[wz].la[0]=0,t[wz].la[1]=1; else if(t[wz].la[1]) t[wz].la[1]=0,t[wz].la[0]=1; if(!t[wz].la[0]&&!t[wz].la[1]) t[wz].lqf=!t[wz].lqf; t[wz].sum=t[wz].r-t[wz].l+1-t[wz].sum; swap(t[wz].sum0,t[wz].sum1); } else { if(t[wz].la[0]) fg(0,wz*2,1,n),fg(0,wz*2+1,1,n); if(t[wz].la[1]) fg(1,wz*2+1,1,n),fg(1,wz*2,1,n); if(t[wz].lqf) qf(wz*2,1,n),qf(wz*2+1,1,n); t[wz].lqf=t[wz].la[0]=t[wz].la[1]=0; if(t[wz*2].r>=l) qf(wz*2,l,r); if(t[wz*2+1].l<=r) qf(wz*2+1,l,r); t[wz].sum=t[wz*2].sum+t[wz*2+1].sum; int mid=(t[wz].l+t[wz].r)/2; if(t[wz*2].lz==mid-t[wz].l+1) { t[wz].lz=mid-t[wz].l+1; if(t[wz*2].ll==t[wz*2+1].ll) t[wz].lz+=t[wz*2+1].lz; } else t[wz].lz=t[wz*2].lz; t[wz].ll=t[wz*2].ll; if(t[wz*2+1].rz==t[wz].r-mid) { t[wz].rz=t[wz].r-mid; if(t[wz*2+1].rr==t[wz*2].rr) t[wz].rz+=t[wz*2].rz; } else t[wz].rz=t[wz*2+1].rz; t[wz].rr=t[wz*2+1].rr; t[wz].sum1=max(t[wz*2].sum1,t[wz*2+1].sum1); if(t[wz*2].rr&&t[wz*2+1].ll&&t[wz*2].rz+t[wz*2+1].lz>t[wz].sum1) t[wz].sum1=t[wz*2].rz+t[wz*2+1].lz; t[wz].sum0=max(t[wz*2].sum0,t[wz*2+1].sum0); if(!t[wz*2].rr&&!t[wz*2+1].ll&&t[wz*2].rz+t[wz*2+1].lz>t[wz].sum0) t[wz].sum0=t[wz*2].rz+t[wz*2+1].lz; } } int findsum(int wz,int l,int r) { if(t[wz].la[0]) fg(0,wz*2,1,n),fg(0,wz*2+1,1,n); if(t[wz].la[1]) fg(1,wz*2+1,1,n),fg(1,wz*2,1,n); if(t[wz].lqf) qf(wz*2,1,n),qf(wz*2+1,1,n); t[wz].lqf=0; t[wz].la[0]=0; t[wz].la[1]=0; if(t[wz].l>=l&&t[wz].r<=r) return t[wz].sum; else { int ans=0; if(t[wz*2].r>=l) ans+=findsum(wz*2,l,r); if(t[wz*2+1].l<=r) ans+=findsum(wz*2+1,l,r); return ans; } } int findmax(int wz,int l,int r) { if(t[wz].la[0]) fg(0,wz*2,1,n),fg(0,wz*2+1,1,n); if(t[wz].la[1]) fg(1,wz*2+1,1,n),fg(1,wz*2,1,n); if(t[wz].lqf) qf(wz*2,1,n),qf(wz*2+1,1,n); t[wz].lqf=0; t[wz].la[0]=0; t[wz].la[1]=0; if(t[wz].l>=l&&t[wz].r<=r) return t[wz].sum1; int ans=0; if(t[wz*2].r>=l) ans=max(ans,findmax(wz*2,l,r)); if(t[wz*2+1].l<=r) ans=max(ans,findmax(wz*2+1,l,r)); if(t[wz*2].r>=l&&t[wz*2+1].l<=r&&t[wz*2].rr&&t[wz*2+1].ll) { int lll=min(t[wz*2].rz,t[wz*2].r-l+1); int rrr=min(t[wz*2+1].lz,r-t[wz*2+1].l+1); ans=max(ans,rrr+lll); } return ans; } int main() { //freopen("1.txt","r",stdin); //freopen("1.out","w",stdout); scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) cin>>AA[i]; build(1,1,n); while(m--) { int a,b,c; scanf("%d%d%d",&a,&b,&c); b++; c++; if(a<=1) fg(a,1,b,c); if(a==2) qf(1,b,c); if(a==3) printf("%d\n",findsum(1,b,c)); if(a==4) printf("%d\n",findmax(1,b,c)); } return 0; }