【BZOJ】【P1858】【Scoi2010】【序列操作】【题解】【线段树】

来源:互联网 发布:matlab求矩阵的最小值 编辑:程序博客网 时间:2024/05/18 02:31

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1858

锻炼代码能力的线段树裸题

Code:

#include<cstdio>#include<iostream>#include<algorithm>#include<cctype>#define lson i<<1,l,mid#define rson i<<1|1,mid+1,r#define L i<<1#define R i<<1|1using namespace std;const int maxn=1e5+5;int a[maxn];int n,m;int getint(){int res=0;char c=getchar();while(!isdigit(c))c=getchar();while(isdigit(c))res=res*10+c-'0',c=getchar();return res;}struct tup{int x,y,z;tup(int _x=0,int _y=0,int _z=0):x(_x),y(_y),z(_z){}};int max5(int a,int b,int c,int d,int e){return max(e,max(max(a,b),max(c,d)));}struct seg_tree{struct node{int lazy,rev,sum0,sum1,ls1,ss1,rs1,ls0,rs0,ss0;node(){lazy=-1,rev=0,sum0=0,sum1=0,ls1=0,ss1=0,rs1=0,ls0=0,rs0=0,ss0=0;}}t[maxn<<2];void build(int i,int l,int r){if(l==r){t[i].sum0=t[i].ls0=t[i].ss0=t[i].rs0=a[l]==0;t[i].sum1=t[i].ls1=t[i].ss1=t[i].rs1=a[l]==1;return;}int mid=(l+r)>>1;build(lson);build(rson);rz(i,l,r);}void rz(int i,int l,int r){int mid=(l+r)>>1;tup l0,r0,ans;t[i].sum0=t[L].sum0+t[R].sum0;t[i].sum1=t[L].sum1+t[R].sum1;t[i].ls0=t[L].ls0;t[i].rs0=t[R].rs0;t[i].ls1=t[L].ls1;t[i].rs1=t[R].rs1;if(t[L].ls0==(mid-l+1))t[i].ls0=t[L].ls0+t[R].ls0;if(t[L].ls1==(mid-l+1))t[i].ls1=t[L].ls1+t[R].ls1;if(t[R].rs0==(r-mid))t[i].rs0=t[R].rs0+t[L].rs0;if(t[R].rs1==(r-mid))t[i].rs1=t[R].rs1+t[L].rs1;t[i].ss0=max5(t[L].ss0,t[R].ss0,t[i].ls0,t[i].rs0,t[L].rs0+t[R].ls0);t[i].ss1=max5(t[L].ss1,t[R].ss1,t[i].ls1,t[i].rs1,t[L].rs1+t[R].ls1);}void pushdown(int i,int l,int r){int mid=(l+r)>>1;if(t[i].rev){swap(t[L].sum0,t[L].sum1);swap(t[L].ls1,t[L].ls0);swap(t[L].ss1,t[L].ss0);swap(t[L].rs1,t[L].rs0);swap(t[R].sum0,t[R].sum1);swap(t[R].ls1,t[R].ls0);swap(t[R].ss1,t[R].ss0);swap(t[R].rs1,t[R].rs0);t[L].rev^=1;t[R].rev^=1;if(~t[L].lazy)t[L].lazy^=1;if(~t[R].lazy)t[R].lazy^=1;t[i].rev=0;}if(t[i].lazy!=-1){t[L].lazy=t[i].lazy;t[L].sum0=(mid-l+1)*(t[i].lazy==0);t[L].sum1=(mid-l+1)*(t[i].lazy==1);t[L].ls0=t[L].ss0=t[L].rs0=(mid-l+1)*(t[i].lazy==0);t[L].ls1=t[L].ss1=t[L].rs1=(mid-l+1)*(t[i].lazy==1);t[R].lazy=t[i].lazy;t[R].sum0=(r-mid)*(t[i].lazy==0);t[R].sum1=(r-mid)*(t[i].lazy==1);t[R].ls0=t[R].ss0=t[R].rs0=(r-mid)*(t[i].lazy==0);t[R].ls1=t[R].ss1=t[R].rs1=(r-mid)*(t[i].lazy==1);t[i].lazy=-1;}}void Change(int i,int l,int r,int l0,int r0,int col){if(l0<=l&&r0>=r){t[i].lazy=col;t[i].sum0=(r-l+1)*(t[i].lazy==0);t[i].sum1=(r-l+1)*(t[i].lazy==1);t[i].ls0=t[i].ss0=t[i].rs0=(r-l+1)*(t[i].lazy==0);t[i].ls1=t[i].ss1=t[i].rs1=(r-l+1)*(t[i].lazy==1);return;}pushdown(i,l,r);int mid=(l+r)>>1;if(l0<=mid)Change(lson,l0,r0,col);if(r0>mid)Change(rson,l0,r0,col);rz(i,l,r);}void Rev(int i,int l,int r,int l0,int r0){if(l0<=l&&r0>=r){t[i].rev^=1;if(~t[i].lazy)t[i].lazy^=1;swap(t[i].sum0,t[i].sum1);swap(t[i].ls1,t[i].ls0);swap(t[i].ss1,t[i].ss0);swap(t[i].rs1,t[i].rs0);return;}pushdown(i,l,r);int mid=(l+r)>>1;if(l0<=mid)Rev(lson,l0,r0);if(r0>mid)Rev(rson,l0,r0);rz(i,l,r);}int One(int i,int l,int r,int l0,int r0){if(l0<=l&&r0>=r)return t[i].sum1;pushdown(i,l,r);int mid=(l+r)>>1,ans=0;if(l0<=mid)ans+=One(lson,l0,r0);if(r0>mid)ans+=One(rson,l0,r0);return ans;}tup Sone(int i,int l,int r,int l0,int r0){if(l0<=l&&r0>=r)return tup(t[i].ls1,t[i].ss1,t[i].rs1);pushdown(i,l,r);int mid=(l+r)>>1;tup ans,lef,rig;if(l0<=mid)lef=Sone(lson,l0,r0);if(r0>mid)rig=Sone(rson,l0,r0);if(l0>mid)return rig;if(r0<=mid)return lef;ans.x=lef.x;ans.z=rig.z;if(lef.x==mid-l+1)ans.x=lef.x+rig.x;if(rig.z==r-mid)ans.z=rig.z+lef.z;ans.y=max5(lef.y,rig.y,ans.x,ans.y,lef.z+rig.x);return ans;}}T;int main(){n=getint(),m=getint();for(int i=1;i<=n;i++)a[i]=getint();T.build(1,1,n);while(m--){int op=getint(),l=getint()+1,r=getint()+1;if(op==0){T.Change(1,1,n,l,r,0);}if(op==1){T.Change(1,1,n,l,r,1);}if(op==2){T.Rev(1,1,n,l,r);}if(op==3){printf("%d\n",T.One(1,1,n,l,r));}if(op==4){printf("%d\n",T.Sone(1,1,n,l,r).y);}}return 0;}


0 0