洛谷P2572 [SCOI2010]序列操作

线段树

pushdown写的很浪~

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define MAXN 100000+10
using namespace std;
struct Node{
    int L,R;
    int tag;
    int num[2];
    int lcon[2],rcon[2],mcon[2];
    Node(){
        L=R=tag=0;
        num[0]=num[1]=0;
        lcon[1]=rcon[1]=mcon[1]=0;
        lcon[0]=rcon[0]=mcon[0]=0;
    }
}dat[MAXN<<2];
int n,m;
int a[MAXN];
Node Merge(Node A,Node B){
    if(A.L<0)return B;
    if(B.L<0)return A;
    Node ret;
    ret.L=A.L,ret.R=B.R;
    int ls=A.R-A.L,rs=B.R-B.L;
    for(int i=0;i<=1;i++){
        ret.num[i]=A.num[i]+B.num[i];
        if(A.num[i]==ls)ret.lcon[i]=ls+B.lcon[i];
        else ret.lcon[i]=A.lcon[i];
        if(B.num[i]==rs)ret.rcon[i]=rs+A.rcon[i];
        else ret.rcon[i]=B.rcon[i];
        ret.mcon[i]=max(A.mcon[i],B.mcon[i]);
        ret.mcon[i]=max(ret.mcon[i],A.rcon[i]+B.lcon[i]);
    }
    return ret;
}    
void c(Node &A,int x){
    x--;
    int size=A.R-A.L;
    A.num[x]=size,A.num[x^1]=0;
    A.lcon[x]=A.rcon[x]=A.mcon[x]=size;
    A.lcon[x^1]=A.rcon[x^1]=A.mcon[x^1]=0;
    A.tag=x+1;
}
void r(Node &A){
    swap(A.num[0],A.num[1]);
    swap(A.lcon[0],A.lcon[1]);
    swap(A.rcon[0],A.rcon[1]);
    swap(A.mcon[0],A.mcon[1]);
    A.tag=3;
}
void update(Node &A,int x){
    if(x<=2){c(A,x);return;}
    if(!A.tag){
        r(A);
    }
    else if(A.tag<=2){
        c(A,((A.tag-1)^1)+1);
    }
    else{
        r(A);
        A.tag=0;
    }
}
void pushdown(int k){
    if(!dat[k].tag)return;
    update(dat[k<<1],dat[k].tag);
    update(dat[k<<1|1],dat[k].tag);
    dat[k].tag=0;
}
void build(int k,int L,int R){
    if(L+1==R){
        dat[k].L=L,dat[k].R=R;
        if(a[L]){dat[k].num[1]=dat[k].lcon[1]=dat[k].rcon[1]=dat[k].mcon[1]=1;}
        else    {dat[k].num[0]=dat[k].lcon[0]=dat[k].rcon[0]=dat[k].mcon[0]=1;}
        return;
    }
    build(k<<1,L,(L+R)>>1);
    build(k<<1|1,(L+R)>>1,R);
    dat[k]=Merge(dat[k<<1],dat[k<<1|1]);
}
void rev(int a,int b,int k){
    int L=dat[k].L,R=dat[k].R;
    if(b<=L||R<=a){
        return;
    }
    else if(a<=L&&R<=b){
        update(dat[k],3);
    }
    else{
        pushdown(k);
        rev(a,b,k<<1);
        rev(a,b,k<<1|1);
        dat[k]=Merge(dat[k<<1],dat[k<<1|1]);
    }
}
void cha(int a,int b,int k,int x){
    int L=dat[k].L,R=dat[k].R;
    if(b<=L||R<=a){
        return;
    }
    else if(a<=L&&R<=b){
        update(dat[k],x);
    }
    else{
        pushdown(k);
        cha(a,b,k<<1,x);
        cha(a,b,k<<1|1,x);
        dat[k]=Merge(dat[k<<1],dat[k<<1|1]);
    }
}
Node query(int a,int b,int k){
    int L=dat[k].L,R=dat[k].R;
    if(b<=L||R<=a){
        Node ret;ret.L=-1;
        return ret;
    }    
    else if(a<=L&&R<=b){
        return dat[k];
    }    
    else{    
        pushdown(k);
        Node lc=query(a,b,k<<1);
        Node rc=query(a,b,k<<1|1);
        return Merge(lc,rc);
    }
}
int main()
{
//    freopen("data.in","r",stdin);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    build(1,1,n+1);
    int opt,x,y;
    while(m--){
        scanf("%d%d%d",&opt,&x,&y);x++,y++;
        if(0==opt||opt==1){
            cha(x,y+1,1,opt+1);
        }
        else if(2==opt){
            rev(x,y+1,1);
        }
        else{
            Node ans=query(x,y+1,1);
            printf("%d\n",(3==opt?ans.num[1]:ans.mcon[1]));
        }
    }
    return 0;
}    

 

posted @ 2017-12-24 23:22  white_hat_hacker  阅读(130)  评论(0编辑  收藏  举报