没过样例,求助

P2572 [SCOI2010] 序列操作

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的时候也发了贴,全是 qndmx


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;

|