zoukankan      html  css  js  c++  java
  • HDU 3397 线段树

    WA了好几发。。。细节颇多,总之写线段树就要写好pushdown和pushup函数

    拍了300组数据才找到错误- -||新技能Get

    #include"cstdio"
    #include"queue"
    #include"cmath"
    #include"stack"
    #include"iostream"
    #include"algorithm"
    #include"cstring"
    #include"queue"
    #include"map"
    #include"vector"
    #define ll long long
    #define mems(a,b) memset(a,b,sizeof(a))
    #define ls pos<<1
    #define rs pos<<1|1
    
    using namespace std;
    const int MAXN = 1e5+50;
    const int MAXE = 200500;
    const int INF = 0x3f3f3f;
    
    struct Node{
        int l,r;
        int num[2];
        int lazy[3];///0为置零1为置一2为翻转
        int lc[2][2];///最大left/right连续长度
        int mc[2];    ///最大长度
    }node[MAXN<<2];
    int x[MAXN];
    
    void pushup(int pos){
        for(int i=0;i<2;i++) node[pos].num[i]=node[ls].num[i]+node[rs].num[i];
        int l=node[pos].l,r=node[pos].r,mid=(l+r)>>1;
    
        for(int i=0;i<2;i++){
            if(node[ls].num[i]==mid-l+1) node[pos].lc[0][i]=node[ls].num[i]+node[rs].lc[0][i];  ///只有在左区间全为0或1时才能这样更新
            else node[pos].lc[0][i]=node[ls].lc[0][i];
        }
        for(int i=0;i<2;i++){
            if(node[rs].num[i]==r-mid) node[pos].lc[1][i]=node[rs].num[i]+node[ls].lc[1][i];    ///同上
            else node[pos].lc[1][i]=node[rs].lc[1][i];
        }
    
        for(int i=0;i<2;i++) node[pos].mc[i]=max(node[ls].mc[i],node[rs].mc[i]);
        for(int i=0;i<2;i++) node[pos].mc[i]=max(node[pos].mc[i],node[ls].lc[1][i]+node[rs].lc[0][i]);///可以是左右区间的最大个数,也可能是连接后的个数
    }
    
    void pushdown(int pos){
        for(int i=0;i<2;i++)
            if(node[pos].lazy[i]){
                node[ls].lazy[i]=node[rs].lazy[i]=node[pos].lazy[i];
                node[ls].lazy[!i]=node[ls].lazy[2]=0;
                node[ls].mc[i]=node[ls].num[i]=node[ls].r-node[ls].l+1;
                node[ls].mc[!i]=node[ls].num[!i]=0;
    
                node[rs].lazy[!i]=node[rs].lazy[2]=0;
                node[rs].mc[i]=node[rs].num[i]=node[rs].r-node[rs].l+1;
                node[rs].mc[!i]=node[rs].num[!i]=0;
                for(int j=0;j<2;j++){
                    node[ls].lc[j][i]=node[ls].r-node[ls].l+1;
                    node[ls].lc[j][!i]=0;
                    node[rs].lc[j][i]=node[rs].r-node[rs].l+1;
                    node[rs].lc[j][!i]=0;
                }
            for(int i=0;i<3;i++) node[pos].lazy[i]=0;   ///如果已经置数,那么翻转标记就无用了
            }
        if(node[pos].lazy[2]){
            node[ls].lazy[2]^=1;
            node[rs].lazy[2]^=1;    ///写成直接=node[pos].lazy[2]WA了半天 - -||
    
            swap(node[ls].mc[0],node[ls].mc[1]);
            swap(node[ls].num[0],node[ls].num[1]);
            swap(node[ls].lazy[0],node[ls].lazy[1]);
    
            swap(node[rs].mc[0],node[rs].mc[1]);
            swap(node[rs].num[0],node[rs].num[1]);
            swap(node[rs].lazy[0],node[rs].lazy[1]);
            for(int i=0;i<2;i++){
                swap(node[ls].lc[i][0],node[ls].lc[i][1]);
                swap(node[rs].lc[i][0],node[rs].lc[i][1]);
            }
            node[pos].lazy[2]=0;
        }
    }
    
    void build(int l,int r,int pos){
        node[pos].l=l;
        node[pos].r=r;
        for(int i=0;i<3;i++) node[pos].lazy[i]=0;
        if(l==r){
            node[pos].num[x[l]]=1;
            node[pos].num[!x[l]]=0;
            node[pos].mc[x[l]]=1;
            node[pos].mc[!x[l]]=0;
            for(int i=0;i<2;i++){
                node[pos].lc[i][x[l]]=1;
                node[pos].lc[i][!x[l]]=0;
            }
            return;
        }
        int mid=(l+r)>>1;
        build(l,mid,ls);
        build(mid+1,r,rs);
        pushup(pos);
    }
    
    void update(int l,int r,int pos,int kind){
        if(l<=node[pos].l&&node[pos].r<=r){
            if(kind==2){
                node[pos].lazy[kind]^=1;
                swap(node[pos].mc[0],node[pos].mc[1]);
                swap(node[pos].num[0],node[pos].num[1]);
                swap(node[pos].lazy[0],node[pos].lazy[1]);
                for(int i=0;i<2;i++) swap(node[pos].lc[i][0],node[pos].lc[i][1]);
            }
            else if(!node[pos].lazy[kind]){
                node[pos].lazy[kind]=1;
                node[pos].lazy[!kind]=0;
                node[pos].lazy[2]=0;
                node[pos].mc[kind]=node[pos].num[kind]=node[pos].r-node[pos].l+1;
                node[pos].mc[!kind]=node[pos].num[!kind]=0;
                for(int j=0;j<2;j++){
                    node[pos].lc[j][kind]=node[pos].r-node[pos].l+1;
                    node[pos].lc[j][!kind]=0;
                }
            }
            return;
        }
        pushdown(pos);
        int mid=(node[pos].l+node[pos].r)>>1;
        if(l<=mid) update(l,r,ls,kind);
        if(r>mid) update(l,r,rs,kind);
        pushup(pos);
    }
    
    int queryone(int l,int r,int pos){
        int ans=0;
        if(l<=node[pos].l&&node[pos].r<=r){
            return node[pos].num[1];
        }
        pushdown(pos);
        int mid=(node[pos].l+node[pos].r)>>1;
        if(l<=mid) ans+=queryone(l,r,ls);
        if(r>mid) ans+=queryone(l,r,rs);
        return ans;
    }
    
    int query_maxlen(int l,int r,int pos){
        if(l==node[pos].l&&node[pos].r==r){
            return node[pos].mc[1];
        }
        pushdown(pos);
        int mid=(node[pos].l+node[pos].r)>>1;
        if(r<=mid) return query_maxlen(l,r,ls);
        else if(l>mid) return query_maxlen(l,r,rs);
        else {
            int ans=max(query_maxlen(l,mid,ls),query_maxlen(mid+1,r,rs));
            int a=min(node[ls].lc[1][1],mid-l+1);
            int b=min(node[rs].lc[0][1],r-mid);
            ans=max(ans,a+b);
            return ans;
        }
    }
    int main(){
        //freopen("in.txt","r",stdin);
        //freopen("pending.txt","w",stdout);
        int n,m,T;scanf("%d",&T);
        while(T--){
            scanf("%d%d",&n,&m);
            for(int i=0;i<n;i++) scanf("%d",&x[i]);
            build(0,n-1,1);
            int a,b,op;
            for(int i=0;i<m;i++){
                scanf("%d%d%d",&op,&a,&b);
                if(op==0||op==1||op==2) update(a,b,1,op);
                else if(op==3) printf("%d
    ",queryone(a,b,1));
                else if(op==4) printf("%d
    ",query_maxlen(a,b,1));
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    OleDbCommand 的用法
    递归求阶乘
    C#重写窗体的方法
    HDU 5229 ZCC loves strings 博弈
    HDU 5228 ZCC loves straight flush 暴力
    POJ 1330 Nearest Common Ancestors LCA
    HDU 5234 Happy birthday 01背包
    HDU 5233 Gunner II 离散化
    fast-IO
    HDU 5265 pog loves szh II 二分
  • 原文地址:https://www.cnblogs.com/luxiaoming/p/5136542.html
Copyright © 2011-2022 走看看