10分求助!!!!

P2572 [SCOI2010] 序列操作

ueettttuj @ 2019-07-02 09:44:59

RT

#include <bits/stdc++.h>
using namespace std;
long long n,m,a[100010];
struct node{
    long long lazy,lcol1,rcol1,sum1,val1,lcol0,rcol0,sum0,val0,chan;
};
node tree[800010];
void pushdown(long long rt,long long l,long long r){
    if(tree[rt].lazy==-1 && tree[rt].chan==1){
        tree[rt].chan=0;

        swap(tree[rt].lcol0,tree[rt].lcol1);
        swap(tree[rt].rcol0,tree[rt].rcol1);
        swap(tree[rt].sum0,tree[rt].sum1);
        swap(tree[rt].val0,tree[rt].val1);

        if(tree[rt*2].lazy!=-1) tree[rt*2].lazy=(tree[rt*2].lazy+1)%2;
        else{
           tree[rt*2].chan=(tree[rt*2].chan+1)%2;
        }
        if(tree[rt*2+1].lazy!=-1) tree[rt*2+1].lazy=(tree[rt*2+1].lazy+1)%2;
        else{
          tree[rt*2+1].chan=(tree[rt*2+1].chan+1)%2;
        }

    }
    if(tree[rt].lazy==1){   
        tree[rt].lcol0=0;
        tree[rt].lcol1=r-l+1;
        tree[rt].rcol0=0;
        tree[rt].rcol1=r-l+1;
        tree[rt].sum0=0;
        tree[rt].sum1=r-l+1;
        tree[rt].val0=0;
        tree[rt].val1=r-l+1;
        tree[rt].lazy=-1;
        tree[rt*2].lazy=1;
        tree[rt*2+1].lazy=1;    
    }
    if(tree[rt].lazy==0){
        tree[rt].lcol0=r-l+1;
        tree[rt].lcol1=0;
        tree[rt].rcol0=r-l+1;
        tree[rt].rcol1=0;
        tree[rt].sum0=r-l+1;
        tree[rt].sum1=0;
        tree[rt].val0=r-l+1;
        tree[rt].val1=0;
        tree[rt].lazy=-1;
        tree[rt*2].lazy=0;
        tree[rt*2+1].lazy=0;    
    }
}
void pushup(long long rt,long long l,long long r){
    long long mid=(l+r)/2;
    if(l==r) return ;
    pushdown(rt*2,l,mid);
    pushdown(rt*2+1,mid+1,r);
    if(tree[rt*2].sum0==mid-l+1){
        tree[rt].lcol0=mid-l+1+tree[rt*2+1].lcol0;
    }
    else tree[rt].lcol0=tree[rt*2].lcol0;
    if(tree[rt*2].sum1==mid-l+1){
        tree[rt].lcol1=mid-l+1+tree[rt*2+1].lcol1;
    }
    else tree[rt].lcol1=tree[rt*2].lcol1;

    if(tree[rt*2+1].sum0==r-mid){
        tree[rt].rcol0=r-mid+tree[rt*2].rcol0;
    }
    else tree[rt].rcol0=tree[rt*2+1].rcol0;
    if(tree[rt*2+1].sum1==r-mid){
        tree[rt].rcol1=r-mid+tree[rt*2].rcol1;
    }
    else tree[rt].rcol1=tree[rt*2+1].rcol1;

    tree[rt].sum0=tree[rt*2].sum0+tree[rt*2+1].sum0;
    tree[rt].sum1=tree[rt*2].sum1+tree[rt*2+1].sum1;

    tree[rt].val0=max(tree[rt*2].val0,max(tree[rt*2+1].val0,tree[rt*2].rcol0+tree[rt*2+1].lcol0));
    tree[rt].val1=max(tree[rt*2].val1,max(tree[rt*2+1].val1,tree[rt*2].rcol1+tree[rt*2+1].lcol1));

}
void build(long long rt,long long l,long long r){
    tree[rt].lazy=-1;
    tree[rt].chan=0;
    if(l==r){
        if(a[l]==0){
            tree[rt].lcol0=1;
            tree[rt].lcol1=0;
            tree[rt].rcol0=1;
            tree[rt].rcol1=0;
            tree[rt].sum0=1;
            tree[rt].sum1=0;
            tree[rt].val0=1;
            tree[rt].val1=0;
        }
        if(a[l]==1){
            tree[rt].lcol0=0;
            tree[rt].lcol1=1;
            tree[rt].rcol0=0;
            tree[rt].rcol1=1;
            tree[rt].sum0=0;
            tree[rt].sum1=1;
            tree[rt].val0=0;
            tree[rt].val1=1;            
        }
        return ;
    }
    long long mid=(l+r)/2;
    build(rt*2,l,mid);
    build(rt*2+1,mid+1,r);
    pushup(rt,l,r);
}
void change(long long rt,long long l,long long r,long long x,long long y,long long k){
    if(x<=l && y>=r){
        if(tree[rt].chan==1) tree[rt].chan=0;
        tree[rt].lazy=k;
        return ;
    }
    long long mid=(l+r)/2;
    pushdown(rt,l,r);
    if(x<=mid) change(rt*2,l,mid,x,y,k);
    if(y>mid) change(rt*2+1,mid+1,r,x,y,k);
    pushup(rt,l,r);
}
void change2(long long rt,long long l,long long r,long long x,long long y){
    if(x<=l && y>=r){
        if(tree[rt].lazy==-1) tree[rt].chan=(tree[rt].chan+1)%2;
        else{
            tree[rt].lazy=(tree[rt].lazy+1)%2;
        }
        return ;
    }
    long long mid=(l+r)/2;
    pushdown(rt,l,r);
    if(x<=mid) change2(rt*2,l,mid,x,y);
    if(y>mid) change2(rt*2+1,mid+1,r,x,y);
    pushup(rt,l,r);
}
long long ask(long long rt,long long l,long long r,long long x,long long y){
    pushdown(rt,l,r);
    pushup(rt,l,r);
    if(x<=l && y>=r){
        return tree[rt].sum1;
    }
    long long mid=(l+r)/2;
    long long ans=0;
    if(x<=mid) ans+=ask(rt*2,l,mid,x,y);
    if(y>mid) ans+=ask(rt*2+1,mid+1,r,x,y);
    return ans;
}
long long ask2(long long rt,long long l,long long r,long long x,long long y){
    pushdown(rt,l,r);
    pushup(rt,l,r);
    if(x<=l && y>=r){
        return tree[rt].val1;
    }
    long long mid=(l+r)/2;
    long long ans=0;
    if(x<=mid) ans=max(ans,ask2(rt*2,l,mid,x,y));
    if(y>mid) ans=max(ans,ask2(rt*2+1,mid+1,r,x,y));
    long long xx,yy;
    yy=min(tree[rt*2+1].lcol1,y-mid);
    xx=min(tree[rt*2].rcol1,mid-x+1); 
    ans=max(ans,xx+yy);
    return ans;
}
int main(){
    scanf("%lld %lld",&n,&m);
    for(long long i=1;i<=n;i++)
      scanf("%lld",&a[i]);
    build(1,1,n);
    for(long long i=1;i<=m;i++){
        long long t,b,c;
        scanf("%lld",&t);
        scanf("%lld %lld",&b,&c);
        b=b+1;
        c=c+1;
        if(t==0){
            change(1,1,n,b,c,0);
        }
        if(t==1){
            change(1,1,n,b,c,1);
        }
        if(t==2){
            change2(1,1,n,b,c);
        }
        if(t==3){
            printf("%lld\n",ask(1,1,n,b,c));
        }
        if(t==4){
            printf("%lld\n",ask2(1,1,n,b,c));
        }
    }
    return 0;
}

by ueettttuj @ 2019-07-02 10:19:48

已AC 还是自己靠谱


by _maze @ 2019-07-02 22:03:31

我这个蒟蒻帮不了你qwq


by _maze @ 2019-07-02 22:03:36

@ueettttuj


by Achtoria @ 2019-08-06 14:28:32

@ueettttuj 您改了什么地方啊?


by ueettttuj @ 2019-08-06 16:40:08

@chen_zhang 我查下先


by ueettttuj @ 2019-08-06 16:45:37

@chen_zhang pushdowntree[rt].chan,即区间翻转标记 需要清零


by Achtoria @ 2019-08-06 16:46:10

@ueettttuj 谢谢您


|