FxorG @ 2020-11-28 18:17:42
// tag=1 : 0 tag =2 :1 tag=-1 null
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#define N (int)(1e5+20)
#define ls (cur<<1)
#define rs (ls+1)
#define mid ((l+r)>>1)
using namespace std;
struct tree {
int sum0,sum1,ml1,mr1,ml0,mr0,len,ans0,ans1,tag,tag2;
}t[N<<2];
int a[N];
int n,m;
void push_up(int cur) {
t[cur].sum0=t[ls].sum0+t[rs].sum0;
t[cur].sum1=t[ls].sum1+t[rs].sum1;
if(t[ls].sum0==t[ls].len) t[cur].ml0=t[ls].len+t[rs].ml0;
else t[cur].ml0=t[ls].ml0;
if(t[rs].sum0==t[rs].len) t[cur].mr0=t[rs].len+t[ls].mr0;
else t[cur].mr0=t[rs].mr0;
if(t[ls].sum1==t[ls].len) t[cur].ml1=t[ls].len+t[rs].ml1;
else t[cur].ml1=t[ls].ml1;
if(t[rs].sum1==t[rs].len) t[cur].mr1=t[rs].len+t[ls].mr1;
else t[cur].mr1=t[rs].mr1;
t[cur].ans0=max(max(t[ls].ans0,t[rs].ans0),t[ls].mr0+t[rs].ml0);
t[cur].ans1=max(max(t[ls].ans1,t[rs].ans1),t[ls].mr1+t[rs].ml1);
}
void push_down(int cur) {
if(t[cur].tag==1) {
t[ls].sum0=t[ls].ml0=t[ls].mr0=t[ls].ans0=t[ls].len;
t[ls].sum1=t[ls].ml1=t[ls].mr1=t[ls].ans1=0;
t[ls].tag=1;
t[rs].sum0=t[rs].ml0=t[rs].mr0=t[rs].ans0=t[rs].len;
t[rs].sum1=t[rs].ml1=t[rs].mr1=t[rs].ans1=0;
t[rs].tag=1;
t[cur].tag=0;
} else if(t[cur].tag==2) {
t[ls].sum0=t[ls].ml0=t[ls].mr0=t[ls].ans0=0;
t[ls].sum1=t[ls].ml1=t[ls].mr1=t[ls].ans1=t[ls].len;
t[ls].tag=2;
t[rs].sum0=t[rs].ml0=t[rs].mr0=t[rs].ans0=0;
t[rs].sum1=t[rs].ml1=t[rs].mr1=t[rs].ans1=t[rs].len;
t[rs].tag=2;
t[cur].tag=0;
}
if(t[cur].tag2) {
swap(t[ls].sum0,t[ls].sum1);
swap(t[ls].ml0,t[ls].ml1);
swap(t[ls].mr0,t[ls].mr1);
swap(t[ls].ans0,t[ls].ans1);
swap(t[rs].sum0,t[rs].sum1);
swap(t[rs].ml0,t[rs].ml1);
swap(t[rs].mr0,t[rs].mr1);
swap(t[rs].ans0,t[rs].ans1);
t[ls].tag2^=1; t[rs].tag2^=1;
t[cur].tag2=0;
}
}
void build(int cur,int l,int r) {
t[cur].tag=0;
t[cur].tag2=0;
t[cur].len=r-l+1;
if(l==r) {
t[cur].sum0=t[cur].ml0=t[cur].mr0=t[cur].ans0=a[l]==0;
t[cur].sum1=t[cur].ml1=t[cur].mr1=t[cur].ans1=a[l]==1;
return;
}
build(ls,l,mid); build(rs,mid+1,r);
push_up(cur);
}
void update(int cur,int l,int r,int cl,int cr,int x) {
if(cl<=l&&r<=cr) {
if(x==0) {
t[cur].sum0=t[cur].ml0=t[cur].mr0=t[cur].ans0=t[cur].len;
t[cur].sum1=t[cur].ml1=t[cur].mr1=t[cur].ans1=0;
t[cur].tag=1; t[cur].tag2=0;
} else if(x==1){
t[cur].sum0=t[cur].ml0=t[cur].mr0=t[cur].ans0=0;
t[cur].sum1=t[cur].ml1=t[cur].mr1=t[cur].ans1=t[cur].len;
t[cur].tag=2; t[cur].tag2=0;
} else {
swap(t[cur].sum0,t[cur].sum1);
swap(t[cur].ml0,t[cur].ml1);
swap(t[cur].mr0,t[cur].mr1);
swap(t[cur].ans0,t[cur].ans1);
t[cur].tag2^=1;
}
return;
}
push_down(cur);
if(cl<=mid) update(ls,l,mid,cl,cr,x);
if(cr>mid) update(rs,mid+1,r,cl,cr,x);
push_up(cur);
}
int query2(int cur,int l,int r,int cl,int cr) {
if(cl<=l&&r<=cr) return t[cur].sum1;
push_down(cur);
int ans=0;
if(cl<=mid) ans+=query2(ls,l,mid,cl,cr);
if(cr>mid) ans+=query2(rs,mid+1,r,cl,cr);
return ans;
}
tree query(int cur,int l,int r,int cl,int cr) {
if(cl<=l&&r<=cr) return t[cur];
push_down(cur);
if(cr<=mid) return query(ls,l,mid,cl,cr);
else if(cl>mid) return query(rs,mid+1,r,cl,cr);
else {
tree ans;
tree lans=query(ls,l,mid,cl,cr),rans=query(rs,mid+1,r,cl,cr);
ans.sum1=lans.sum1+rans.sum1;
if(lans.sum1==lans.len) ans.ml1=lans.len+rans.ml1;
else ans.ml1=lans.ml1;
if(rans.sum1==rans.len) ans.mr1=rans.len+lans.mr1;
else ans.mr1=rans.mr1;
ans.ans1=max(max(lans.ans1,rans.ans1),lans.mr1+rans.ml1);
return ans;
}
}
int main() {
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
build(1,1,n);
int opt,x,y;
for(int i=1;i<=m;i++) {
scanf("%d%d%d",&opt,&x,&y);
++x; ++y;
if(opt==0) {
update(1,1,n,x,y,0);
} else if(opt==1) {
update(1,1,n,x,y,1);
} else if(opt==2) {
update(1,1,n,x,y,2);
} else if(opt==3) {
printf("%d\n",query2(1,1,n,x,y));
} else {
printf("%d\n",query(1,1,n,x,y).ans1);
}
}
return 0;
}
by guodong @ 2020-11-28 18:27:30
orz xgf
不过这种题没什么人愿意帮你调的吧..
建议学小粉兔重载合并操作,会方便不少