help

P2572 [SCOI2010] 序列操作

Judgelight @ 2022-08-16 13:02:58

#include<bits/stdc++.h>
#define N 100009
using namespace std;
int n,w[N];
struct Node{
    int u,l,r,sum1,sum0,max1,lmax1,rmax1,max0,lmax0,rmax0,tag,rev;
}tr[N*4];
void pushup(int u){
    tr[u].sum1=tr[u<<1].sum1+tr[u<<1|1].sum1;
    if(tr[u<<1].lmax1==tr[u<<1].r-tr[u<<1].l+1){
        tr[u].lmax1=tr[u<<1].r-tr[u<<1].l+1+tr[u<<1|1].lmax1;
    }
    else tr[u].lmax1=tr[u<<1].lmax1;
    if(tr[u<<1|1].rmax1==tr[u<<1|1].r-tr[u<<1|1].l+1){
        tr[u].rmax1=tr[u<<1|1].r-tr[u<<1|1].l+1+tr[u<<1].rmax1;
    }
    else tr[u].rmax1=tr[u<<1|1].rmax1;
    tr[u].max1=max(tr[u].lmax1,tr[u].rmax1);
    tr[u].max1=max(tr[u].max1,tr[u<<1].rmax1+tr[u<<1|1].lmax1);
//fuck
    tr[u].sum0=tr[u<<1].sum0+tr[u<<1|1].sum0;
    if(tr[u<<1].lmax0==tr[u<<1].r-tr[u<<1].l+1){
        tr[u].lmax0=tr[u<<1].r-tr[u<<1].l+1+tr[u<<1|1].lmax0;
    }
    else tr[u].lmax0=tr[u<<1].lmax0;
    if(tr[u<<1|1].rmax0==tr[u<<1|1].r-tr[u<<1|1].l+1){
        tr[u].rmax0=tr[u<<1|1].r-tr[u<<1|1].l+1+tr[u<<1].rmax0;
    }
    else tr[u].rmax0=tr[u<<1|1].rmax0;
    tr[u].max0=max(tr[u].lmax0,tr[u].rmax0);
    tr[u].max0=max(tr[u].max0,tr[u<<1].rmax0+tr[u<<1|1].lmax0);
}
void pushdown(int u){
    if(tr[u].tag!=-1){
        tr[u].rev=tr[u<<1].rev=tr[u<<1|1].rev=0;
        tr[u<<1].tag=tr[u<<1|1].tag=tr[u].tag;
        if(tr[u].tag==1){
            tr[u<<1].lmax0=tr[u<<1].rmax0=tr[u<<1].max0=tr[u<<1].sum0=0;
            tr[u<<1|1].lmax0=tr[u<<1|1].rmax0=tr[u<<1|1].max0=tr[u<<1|1].sum0=0;
            tr[u<<1].lmax1=tr[u<<1].rmax1=tr[u<<1].max1=tr[u<<1].sum1=tr[u<<1].r-tr[u<<1].l+1;
            tr[u<<1|1].lmax1=tr[u<<1|1].rmax1=tr[u<<1|1].max1=tr[u<<1|1].sum1=tr[u<<1|1].r-tr[u<<1|1].l+1;
        }
        else{
            tr[u<<1].lmax1=tr[u<<1].rmax1=tr[u<<1].max1=tr[u<<1].sum1=0;
            tr[u<<1|1].lmax1=tr[u<<1|1].rmax1=tr[u<<1|1].max1=tr[u<<1|1].sum1=0;
            tr[u<<1].lmax0=tr[u<<1].rmax0=tr[u<<1].max0=tr[u<<1].sum0=tr[u<<1].r-tr[u<<1].l+1;
            tr[u<<1|1].lmax0=tr[u<<1|1].rmax0=tr[u<<1|1].max0=tr[u<<1|1].sum0=tr[u<<1|1].r-tr[u<<1|1].l+1;
        }
        tr[u].tag=-1;
        return ;
    }
//fuck
    if(tr[u].rev==0){
        return ;
    }
    tr[u<<1].sum1=(tr[u<<1].r-tr[u<<1].l+1)-tr[u<<1].sum1;
    tr[u<<1|1].sum1=(tr[u<<1|1].r-tr[u<<1|1].l+1)-tr[u<<1].sum1;
    tr[u<<1].sum0=(tr[u<<1].r-tr[u<<1].l+1)-tr[u<<1].sum0;
    tr[u<<1|1].sum0=(tr[u<<1|1].r-tr[u<<1|1].l+1)-tr[u<<1].sum0;
    if(tr[u<<1].tag!=-1){
        if(tr[u<<1].tag==1){
            tr[u<<1].tag=0;
        }
        else{
            tr[u<<1].tag=1;
        }
    }
    else{
        if(tr[u<<1].rev==1){
            tr[u<<1].rev=0;
        }
        else{
            tr[u<<1].rev=1;
        }
    }
    if(tr[u<<1|1].tag!=-1){
        if(tr[u<<1|1].tag==1){
            tr[u<<1|1].tag=0;
        }
        else{
            tr[u<<1|1].tag=1;
        }
    }
    else{
        if(tr[u<<1|1].rev==1){
            tr[u<<1|1].rev=0;
        }
        else{
            tr[u<<1|1].rev=1;
        }
    }
    swap(tr[u<<1].max1,tr[u<<1].max0);
    swap(tr[u<<1].lmax1,tr[u<<1].lmax0);
    swap(tr[u<<1].rmax1,tr[u<<1].rmax0);
    swap(tr[u<<1|1].max1,tr[u<<1|1].max0);
    swap(tr[u<<1|1].lmax1,tr[u<<1|1].lmax0);
    swap(tr[u<<1|1].rmax1,tr[u<<1|1].rmax0);
    tr[u].rev=0;
}
void build(int u,int l,int r){
    tr[u].l=l,tr[u].r=r,tr[u].tag=-1,tr[u].rev=0;
    if(l==r){
        tr[u].sum1=tr[u].max1=tr[u].lmax1=tr[u].rmax1=w[l];
        tr[u].sum0=tr[u].max0=tr[u].lmax0=tr[u].rmax0=!w[l];
        return ;
    }
    int mid=l+r>>1;
    build(u<<1,l,mid);
    build(u<<1|1,mid+1,r);
    pushup(u);
}
void modify(int u,int l,int r,int x){
    if(tr[u].l>=l&&tr[u].r<=r){
        if(x==0||x==1){
            tr[u].sum1=(tr[u].r-tr[u].l+1)*x;
            tr[u].sum0=(tr[u].r-tr[u].l+1)*(!x);
            tr[u].tag=x;
            if(x==1){
                tr[u].max1=tr[u].lmax1=tr[u].rmax1=tr[u].r-tr[u].l+1;
                tr[u].max0=tr[u].lmax0=tr[u].rmax0=0;
            }
            else{
                tr[u].max0=tr[u].lmax0=tr[u].rmax0=tr[u].r-tr[u].l+1;
                tr[u].max1=tr[u].lmax1=tr[u].rmax1=0;
            }
        }
        else{
            tr[u].sum1=(tr[u].r-tr[u].l+1)-tr[u].sum1;
            tr[u].sum0=(tr[u].r-tr[u].l+1)-tr[u].sum0;
            tr[u].rev=!tr[u].rev;
            swap(tr[u].max1,tr[u].max0);
            swap(tr[u].lmax1,tr[u].lmax0);
            swap(tr[u].rmax1,tr[u].rmax0); 
        }
        return ;
    }
    pushdown(u); 
    int mid=tr[u].l+tr[u].r>>1;
    if(l<=mid){
        modify(u<<1,l,r,x);
    }
    if(r>mid){
        modify(u<<1|1,l,r,x);
    }
    pushup(u);
}
int query(int u,int l,int r){
    if(tr[u].l>=l&&tr[u].r<=r){
        return tr[u].sum1;
    }
    pushdown(u);
    int mid=tr[u].l+tr[u].r>>1,ans=0;
    if(l<=mid){
        ans+=query(u<<1,l,r);
    }
    if(r>mid){
        ans+=query(u<<1|1,l,r);
    }
    return ans;
}
Node qmax(int u,int l,int r){
    if(tr[u].l>=l&&tr[u].r<=r){
        return tr[u];
    }
    pushdown(u);
    int mid=tr[u].l+tr[u].r>>1;
    if(r<=mid){
        return qmax(u<<1,l,r);
    }
    if(l>mid){
        return qmax(u<<1|1,l,r);
    }
    Node vex,left=qmax(u<<1,l,r),right=qmax(u<<1|1,l,r);
    vex.sum1=left.sum1+right.sum1;
    if(left.lmax1==left.r-left.l+1){
        vex.lmax1=left.r-left.l+1+right.lmax1;
    }
    else vex.lmax1=left.lmax1;
    if(right.rmax1==right.r-right.l+1){
        vex.rmax1=right.r-right.l+1+left.rmax1;
    }
    else vex.rmax1=right.rmax1;
    vex.max1=max(vex.lmax1,vex.rmax1);
    vex.max1=max(vex.max1,left.rmax1+right.lmax1);
//fuck
    vex.sum0=left.sum0+right.sum0;
    if(left.lmax0==left.r-left.l+1){
        vex.lmax0=left.r-left.l+1+right.lmax0;
    }
    else vex.lmax0=left.lmax0;
    if(right.rmax0==right.r-right.l+1){
        vex.rmax0=right.r-right.l+1+left.rmax0;
    }
    else vex.rmax0=right.rmax0;
    vex.max0=max(vex.lmax0,vex.rmax0);
    vex.max0=max(vex.max0,left.rmax0+right.lmax0);
    return vex;
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>w[i];
    }
    build(1,1,n);
    for(int i=1;i<=n;i++){
        int q,l,r;
        cin>>q>>l>>r;
        if(q==0){
            modify(1,l,r,0);
        }
        else if(q==1){
            modify(1,l,r,1);
        }
        else if(q==3){
            cout<<query(1,l,r)<<endl;
        }
        else{
            cout<<qmax(1,l,r).max1<<endl;
        }
    }
    return 0;
}

by ljlawa @ 2022-08-16 13:13:58

真刑哈,建议放剪切板

代码line20,52,182违禁警告


by ljlawa @ 2022-08-16 13:14:28

@lijiale2008 改,185


|