HDU 3397 Sequence operation

 给出一个长度为N(N <= 100000)的数列,然后是五种操作:
插入操作:
0 a b 将所有[a, b]区间内的数改成0
1 a b 将所有[a, b]区间内的数改成1
2 a b 将所有[a, b]区间内的数异或一下(0边1,1变0)
输出操作:
3 a b 输出[a, b]区间内1的数量
4 a b 输出[a, b]区间内最长的连续1串
setbuf太坑了  一直TLE T_T  去掉就过了
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define for if(0); else for
struct SegNode{
    int lc[2],rc[2],cc[2];
    int sum[2];
    char color,xorflag,emptyflag;
};
const int N=65536*2+10;
struct SegTree{
    SegNode a[N<<2];
    int n,Q;
    void Init(int n){
        for(Q=1;Q<=n+2;Q<<=1);
        this->n=n;
    }
    void cover(int rt,int c,int L){
        SegNode &x=a[rt];
        x.lc[c]=x.rc[c]=x.cc[c]=x.sum[c]=L;
        x.lc[c^1]=x.rc[c^1]=x.cc[c^1]=x.sum[c^1]=0;
        x.color=c;
        x.xorflag=0;
        x.emptyflag=0;
    }
    void XOR(int rt,int L){
        SegNode &x=a[rt];
        if(x.color!=-1){
            x.color^=1;
            cover(rt,x.color,L);
        }else {
            swap(x.lc[0],x.lc[1]);
            swap(x.rc[0],x.rc[1]);
            swap(x.cc[0],x.cc[1]);
            swap(x.sum[0],x.sum[1]);
            x.xorflag^=1;
        }
    }
    SegNode merge(const SegNode &l,const SegNode &r,int L,int mode=0)const {
        if(l.emptyflag) return r;
        SegNode ret;
        for(int i=0;i<2;i++){
            if(i==0 &&mode )continue;
            ret.lc[i]=l.lc[i];
            ret.rc[i]=r.rc[i];
            ret.cc[i]=max(max(l.cc[i],r.cc[i]),l.rc[i]+r.lc[i]);
            if(l.lc[i]==L>>1) ret.lc[i]+=r.lc[i];
            if(r.rc[i]==L>>1) ret.rc[i]+=l.rc[i];
            ret.sum[i]=l.sum[i]+r.sum[i];
        }
        ret.color=(l.color==r.color)?l.color:-1;
        ret.xorflag=ret.emptyflag=0;
        return ret;
    }
    void pushdown(int rt,int L){
        if(a[rt].color!=-1){
            cover(rt<<1,a[rt].color,L>>1);
            cover(rt<<1|1,a[rt].color,L>>1);}
        if(a[rt].xorflag){
            XOR(rt<<1,L>>1);
            XOR(rt<<1|1,L>>1);
            a[rt].xorflag=0;}
    }
    void pushup(int rt,int L){
        if(rt>=Q) return;
        a[rt]=merge(a[rt<<1],a[rt<<1|1],L);
    }
    void update(int L,int R,int l,int r,int rt,int op){
        if(op<2 &&a[rt].color==op) return;
        if(L<=l && r<=R){
            if(op<2) cover(rt,op,r-l+1);
            else XOR(rt,r-l+1);
            return;
        }
        int m=(l+r)>>1;
        if(rt>=Q) return;
        pushdown(rt,r-l+1);
        if(L<=m) update(L,R,l,m,rt<<1,op);
        if(m<R) update(L,R,m+1,r,rt<<1|1,op);
        pushup(rt,r-l+1);
    }
    SegNode query(int L,int R,int l,int r,int rt){
        SegNode ret;
        ret.emptyflag=1;
        if(L<=l && r<=R){
            return a[rt];
        }
        if(rt>=Q) return ret;
        int m=(l+r)>>1;
        pushdown(rt,r-l+1);
        if(L<=m) ret=merge(ret,query(L,R,l,m,rt<<1),r-l+1);
        if(m<R) ret=merge(ret,query(L,R,m+1,r,rt<<1|1),r-l+1);
        return ret;
    }
    void update(int L,int R,int op){
        update(L,R,0,Q-1,1,op);
    }
    SegNode query(int L,int R){
        return query(L,R,0,Q-1,1);
    }
}st;

int T,n,m;
int main() {
    scanf("%d",&T);
    while(T--){
        scanf("%d %d",&n,&m);
        st.Init(n+10);
        for(int i=1;i<=n;i++){
            int x;
            scanf("%d",&x);
            st.update(i,i,x);
        }
        for(int i=0;i<m;i++){
            int op,l,r;
            scanf("%d %d %d",&op,&l,&r);
            l++,r++;
            if(op<=2){
                st.update(l,r,op);
            }else{
                SegNode ans=st.query(l,r);
                if(op==3){
                    printf("%d\n",ans.sum[1]);
                }else if(op==4){
                    printf("%d\n",ans.cc[1]);
                }
            }
        }
    }
    return 0;
}
posted @ 2012-08-09 11:38  编程菜菜  阅读(142)  评论(0编辑  收藏  举报