http://www.lydsy.com/JudgeOnline/problem.php?id=1858
2018 自己写的第1题,一遍过
^_^
元旦快乐
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; #define N 100001 struct node { int siz; int L[2],R[2],con[2]; int sum[2]; bool rev; int cover; }tr[N<<2]; struct node_ { int L1,R1,con1; int siz; }; node_ operator + (node_ l,node_ r) { node_ res; res.L1=l.L1; if(l.L1==l.siz) res.L1+=r.L1; res.R1=r.R1; if(r.R1==r.siz) res.R1+=l.R1; res.con1=max(l.con1,r.con1); res.con1=max(res.con1,l.R1+r.L1); return res; } int x; int ans; void read(int &x) { x=0; char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) { x=x*10+c-‘0‘; c=getchar(); } } void update(int k) { for(int i=0;i<=1;++i) { tr[k].L[i]=tr[k<<1].L[i]; if(tr[k<<1].L[i]==tr[k<<1].siz) tr[k].L[i]+=tr[k<<1|1].L[i]; tr[k].R[i]=tr[k<<1|1].R[i]; if(tr[k<<1|1].R[i]==tr[k<<1|1].siz) tr[k].R[i]+=tr[k<<1].R[i]; tr[k].con[i]=max(tr[k<<1].con[i],tr[k<<1|1].con[i]); tr[k].con[i]=max(tr[k].con[i],tr[k<<1].R[i]+tr[k<<1|1].L[i]); tr[k].sum[i]=tr[k<<1].sum[i]+tr[k<<1|1].sum[i]; } } void build(int k,int l,int r) { tr[k].cover=-1; tr[k].siz=r-l+1; if(l==r) { read(x); tr[k].L[x]++; tr[k].R[x]++; tr[k].con[x]++; tr[k].sum[x]++; return; } int mid=l+r>>1; build(k<<1,l,mid); build(k<<1|1,mid+1,r); update(k); } void reverse(int k) { swap(tr[k].L[0],tr[k].L[1]); swap(tr[k].R[0],tr[k].R[1]); swap(tr[k].con[0],tr[k].con[1]); swap(tr[k].sum[0],tr[k].sum[1]); tr[k].rev^=1; if(tr[k].cover!=-1) tr[k].cover^=1; } void down_rev(int k) { reverse(k<<1); reverse(k<<1|1); tr[k].rev^=1; } void covering(int k,int w) { tr[k].L[w]=tr[k].R[w]=tr[k].con[w]=tr[k].sum[w]=tr[k].siz; tr[k].L[w^1]=tr[k].R[w^1]=tr[k].con[w^1]=tr[k].sum[w^1]=0; tr[k].cover=w; tr[k].rev=false; } void down_cov(int k) { covering(k<<1,tr[k].cover); covering(k<<1|1,tr[k].cover); tr[k].cover=-1; } void Cover(int k,int l,int r,int opl,int opr,int w) { if(l>=opl && r<=opr) { covering(k,w); return; } if(tr[k].rev) down_rev(k); if(tr[k].cover!=-1) down_cov(k); int mid=l+r>>1; if(opl<=mid) Cover(k<<1,l,mid,opl,opr,w); if(opr>mid) Cover(k<<1|1,mid+1,r,opl,opr,w); update(k); } void Reverse(int k,int l,int r,int opl,int opr) { if(l>=opl && r<=opr) { reverse(k); return; } if(tr[k].rev) down_rev(k); if(tr[k].cover!=-1) down_cov(k); int mid=l+r>>1; if(opl<=mid) Reverse(k<<1,l,mid,opl,opr); if(opr>mid) Reverse(k<<1|1,mid+1,r,opl,opr); update(k); } void query(int k,int l,int r,int opl,int opr) { if(l>=opl && r<=opr) { ans+=tr[k].sum[1]; return; } if(tr[k].rev) down_rev(k); if(tr[k].cover!=-1) down_cov(k); int mid=l+r>>1; if(opl<=mid) query(k<<1,l,mid,opl,opr); if(opr>mid) query(k<<1|1,mid+1,r,opl,opr); } node_ Query(int k,int l,int r,int opl,int opr) { if(l>=opl && r<=opr) { node_ res; res.L1=tr[k].L[1]; res.R1=tr[k].R[1]; res.con1=tr[k].con[1]; res.siz=tr[k].siz; return res; } if(tr[k].rev) down_rev(k); if(tr[k].cover!=-1) down_cov(k); int mid=l+r>>1; if(opr<=mid) return Query(k<<1,l,mid,opl,opr); if(opl>mid) return Query(k<<1|1,mid+1,r,opl,opr); return Query(k<<1,l,mid,opl,opr)+Query(k<<1|1,mid+1,r,opl,opr); } int main() { int n,m; read(n); read(m); build(1,1,n); int ty,l,r; while(m--) { read(ty); read(l); read(r); l++; r++; switch(ty) { case 0 : Cover(1,1,n,l,r,0); break; case 1 : Cover(1,1,n,l,r,1); break; case 2 : Reverse(1,1,n,l,r); break; case 3 : ans=0; query(1,1,n,l,r); cout<<ans<<‘\n‘; break; case 4 : printf("%d\n",Query(1,1,n,l,r).con1); break; } } }