传送门: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|1
using 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;
}