whiteqwq @ 2020-03-21 23:14:12
解释意思:
a[]:原数组
lc,rc:左右儿子
sum:和
lazy:区间赋值标记
rev:区间取反标记
size:区间大小
pre[0/1]:最长连续0/1前缀长度
suf[0/1]:最长连续0/1后缀长度
maxx[0/1]:最大连续0/1子段和
swp():交换两个数
merge():合并两个区间
pushup():数据上传
getlazy():区间直接赋值,记录lazy
getrev():区间直接取反,记录rev
pushdown():标记下传
update():线段树区间赋值
reverse():线段树区间取反
query():线段树区间查询(将答案合并在一起)
#include<stdio.h>
const int maxn=400005;
int i,j,k,m,n;
int a[maxn];
struct SegTree{
int lc,rc,sum,lazy,rev,size;
int pre[2],suf[2],maxx[2];
}zero,st[maxn];
inline int max(int a,int b){
return a>b? a:b;
}
inline void swp(int &a,int &b){
a+=b,b=a-b,a-=b;
}
inline void merge(SegTree &res,SegTree a,SegTree b){
res.sum=a.sum+b.sum;
res.pre[0]=a.pre[0]==a.size? a.size+b.pre[0]:a.pre[0];
res.pre[1]=a.pre[1]==a.size? a.size+b.pre[1]:a.pre[1];
res.suf[0]=b.suf[0]==b.size? b.size+a.suf[0]:b.suf[0];
res.suf[1]=b.suf[1]==b.size? b.size+a.suf[1]:b.suf[1];
res.maxx[0]=max(max(a.maxx[0],b.maxx[0]),a.suf[0]+b.pre[0]);
res.maxx[1]=max(max(a.maxx[1],b.maxx[1]),a.suf[1]+b.pre[1]);
}
inline void pushup(int now){
merge(st[now],st[st[now].lc],st[st[now].rc]);
}
inline void getlazy(int l,int r,int now,int v){
st[now].sum=v*st[now].size;
st[now].pre[v]=st[now].size,st[now].pre[v^1]=0;
st[now].suf[v]=st[now].size,st[now].suf[v^1]=0;
st[now].maxx[v]=st[now].size,st[now].maxx[v^1]=0;
st[now].lazy=v,st[now].rev=0;
}
inline void getrev(int l,int r,int now){
st[now].sum=st[now].size-st[now].sum;
swp(st[now].pre[0],st[now].pre[1]);
swp(st[now].suf[0],st[now].suf[1]);
swp(st[now].maxx[0],st[now].maxx[1]);
st[now].rev^=1;
}
inline void pushdown(int l,int r,int now){
int mid=(l+r)>>1;
if(st[now].lazy!=-1){
getlazy(l,mid,st[now].lc,st[now].lazy);
getlazy(mid+1,r,st[now].rc,st[now].lazy);
st[now].lazy=-1;
}
if(st[now].rev!=0){
getrev(l,mid,st[now].lc);
getrev(mid+1,r,st[now].rc);
st[now].rev=0;
}
}
void build(int l,int r,int now){
st[now]=zero;
st[now].size=r-l+1;
if(l==r){
st[now].sum=st[now].pre[0]=st[now].pre[1]=st[now].suf[0]=st[now].suf[1]=st[now].maxx[0]=st[now].maxx[1]=a[l];
return ;
}
int mid=(l+r)>>1;
st[now].lc=now<<1,st[now].rc=now<<1|1;
build(l,mid,st[now].lc),build(mid+1,r,st[now].rc);
pushup(now);
}
void update(int l,int r,int now,int L,int R,int v){
if(L<=l&&r<=R){
getlazy(l,r,now,v);
return ;
}
int mid=(l+r)>>1;
pushdown(l,r,now);
if(L<=mid)
update(l,mid,st[now].lc,L,R,v);
if(mid<R)
update(mid+1,r,st[now].rc,L,R,v);
pushup(now);
}
void reverse(int l,int r,int now,int L,int R){
if(L<=l&&r<=R){
getrev(l,r,now);
return ;
}
int mid=(l+r)>>1;
pushdown(l,r,now);
if(L<=mid)
reverse(l,mid,st[now].lc,L,R);
if(mid<R)
reverse(mid+1,r,st[now].rc,L,R);
pushup(now);
}
SegTree query(int l,int r,int now,int L,int R){
if(L>r||l>R)
return zero;
if(L<=l&&r<=R)
return st[now];
int mid=(l+r)>>1;
SegTree res=zero;
pushdown(l,r,now);
merge(res,query(l,mid,st[now].lc,L,R),query(mid+1,r,st[now].rc,L,R));
return res;
}
int main(){
zero.lc=zero.rc=zero.sum=zero.rev=zero.pre[0]=zero.pre[1]=zero.suf[0]=zero.suf[1]=zero.maxx[0]=zero.maxx[1]=0,zero.lazy=-1,zero.size=1;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
build(1,n,1);
for(i=1;i<=m;i++){
int opt,l,r;
scanf("%d%d%d",&opt,&l,&r);
l++,r++;
if(opt==0)
update(1,n,1,l,r,0);
if(opt==1)
update(1,n,1,l,r,1);
if(opt==2)
reverse(1,n,1,l,r);
if(opt==3)
printf("%d\n",query(1,n,1,l,r).sum);
if(opt==4)
printf("%d\n",query(1,n,1,l,r).maxx[1]);
}
return 0;
}
by KokiNiwa @ 2020-03-21 23:21:23
你觉得,这种题有人帮你调试嘛?
by momentous @ 2020-03-21 23:25:48
我做GSS7的时候也发了贴,全是
by whiteqwq @ 2020-03-22 09:57:08
我做GSS8的时候发了贴也没人调
by whiteqwq @ 2020-03-22 10:12:40
此贴完结
by whiteqwq @ 2020-03-22 10:14:26
第58行错误
st[now].sum=st[now].pre[0]=st[now].pre[1]=st[now].suf[0]=st[now].suf[1]=st[now].maxx[0]=st[now].maxx[1]=a[l];
应改为
st[now].sum=a[l];
st[now].pre[a[l]]=st[now].suf[a[l]]=st[now].maxx[a[l]]=1;
st[now].pre[a[l]^1]=st[now].suf[a[l]^1]=st[now].maxx[a[l]^1]=0;