zoukankan      html  css  js  c++  java
  • hdu 3911 Black And White (线段树 区间合并)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3911

    题意:

    给你一段01序列,有两个操作:

    1.区间异或,2.询问区间最长的连续的1得长度

    思路:

    线段树区间合并,开六个数组分别表示:

    lsum0   区间左边界开始从左到右连续0的个数

    rsum0   区间右边界开始从右到左连续0的个数

    lsum1  rsum1 根据上面的可以看出

    sum0  区间最长的连续0的个数

    sum1 区间最长的连续1的个数

    碰到i区间异或操作,我们直接奖这几个数组换下就好了

    实现代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define mid int m = (l + r) >> 1
    #define ll long long
    #define ull unsigned long long
    
    const int M = 1e5 + 10;
    int lsum1[M<<2],rsum1[M<<2],sum1[M<<2],lsum0[M<<2],rsum0[M<<2],sum0[M<<2],lazy[M<<2];
    int a[M];
    void pushup(int l,int r,int rt){
        mid;
        lsum1[rt] = lsum1[rt<<1]; lsum0[rt] = lsum0[rt<<1];
        rsum1[rt] = rsum1[rt<<1|1];  rsum0[rt] = rsum0[rt<<1|1];
        if(lsum1[rt] == m-l+1) lsum1[rt] += lsum1[rt<<1|1];
        if(rsum1[rt] == r-m) rsum1[rt] += rsum1[rt<<1];
        if(lsum0[rt] == m-l+1) lsum0[rt] += lsum0[rt<<1|1];
        if(rsum0[rt] == r-m) rsum0[rt] += rsum0[rt<<1];
        sum0[rt] = max(max(sum0[rt<<1],sum0[rt<<1|1]),rsum0[rt<<1]+lsum0[rt<<1|1]);
        sum1[rt] = max(max(sum1[rt<<1],sum1[rt<<1|1]),rsum1[rt<<1]+lsum1[rt<<1|1]);
    }
    
    void swa(int rt){
       swap(lsum0[rt],lsum1[rt]);
       swap(rsum0[rt],rsum1[rt]);
       swap(sum0[rt],sum1[rt]);
    }
    
    void pushdown(int l,int r,int rt){
        if(lazy[rt]){
            lazy[rt<<1] ^= lazy[rt];
            lazy[rt<<1|1] ^= lazy[rt];
            swa(rt<<1); swa(rt<<1|1);
            lazy[rt] = 0;
        }
    }
    
    void build(int l,int r,int rt){
        lazy[rt] = 0;
        lsum1[rt] = rsum1[rt] = sum1[rt] = 0;
        lsum0[rt] = rsum0[rt] = sum0[rt] = 0;
        if(l == r){
            if(a[l]){
                lsum1[rt] = rsum1[rt] = sum1[rt] = 1;
                lsum0[rt] = rsum0[rt] = sum0[rt] = 0;
            }
            else{
                lsum1[rt] = rsum1[rt] = sum1[rt] = 0;
                lsum0[rt] = rsum0[rt] = sum0[rt] = 1;
            }
            return ;
        }
        mid;
        build(lson);  build(rson);
        pushup(l,r,rt);
    }
    
    
    void update(int L,int R,int l,int r,int rt){
        if(L <= l&&R >= r){
            lazy[rt] ^= 1;
            swa(rt);
            return ;
        }
        pushdown(l,r,rt);
        mid;
        if(L <= m) update(L,R,lson);
        if(R > m) update(L,R,rson);
        pushup(l,r,rt);
    }
    
    int query(int L,int R,int l,int r,int rt){
        if(L <= l&&R >= r){
            return sum1[rt];
        }
        pushdown(l,r,rt);
        mid;
        if(L > m) return query(L,R,rson);
        if(R <= m) return query(L,R,lson);
        int t1 = query(L,R,lson);
        int t2 = query(L,R,rson);
        int rs = min(lsum1[rt<<1|1],R-m);
        int ls = min(m-L+1,rsum1[rt<<1]);
        return max(max(t1,t2),ls+rs);
    }
    
    int main()
    {
        int n,op,x,y,q;
        while(scanf("%d",&n)!=EOF){
        for(int i = 1;i <= n;i ++){
            scanf("%d",&a[i]);
        }
        build(1,n,1);
        scanf("%d",&q);
       while(q--){
            scanf("%d%d%d",&op,&x,&y);
            if(op == 1)   update(x,y,1,n,1);
            else printf("%d
    ",query(x,y,1,n,1));
        }
        }
        return 0;
    }
  • 相关阅读:
    技术晨读_20160611
    浏览器退出之后php还会继续执行么?
    大话keepalive
    也说说TIME_WAIT状态
    PHP的错误机制总结
    ASP.NET MVC中使用Unity Ioc Container
    Unity依赖注入使用详解
    小菜学习设计模式(五)—控制反转(Ioc)
    程序员的人性思考(续)
    Delegate、Predicate、Action和Func
  • 原文地址:https://www.cnblogs.com/kls123/p/9780154.html
Copyright © 2011-2022 走看看