• hdu 3911 Black And White(线段树)


    题目连接:hdu 3911 Black And White

    题目大意:给定一个序列,然后有M次操作;

    • 0 l r:表示询问l,r中最大连续1的个数
    • 1 l r:表示将l,r区间上的数取反

    解题思路:线段树的一种题型,区间合并,由于有一个取反的操作,所以对于每一个节点要维护6个值,包含连续0,1最长序列的长度,左边和右边的最长连续长度。须要注意的是,假设询问的区间最大值是从R[lson] + L[rson]来到,要推断是否比长度大于r - l + 1。一開始没注意,所以WA了,上网搜了下别人的题解,发现非常多人在query里面没有pushup更新当前节点信息,这样肯定是不行的,有pushdown,肯定要在更新当前节点信息的。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 1e5 + 5;
    
    int N, M, a[maxn];
    
    #define lson(x) ((x)<<1)
    #define rson(x) (((x)<<1)|1)
    int lc[maxn << 2], rc[maxn << 2], filp[maxn << 2];
    int L[maxn << 2][2], R[maxn << 2][2], S[maxn << 2][2];
    
    void maintain (int u) {
        filp[u] ^= 1;
        swap(L[u][0], L[u][1]);
        swap(R[u][0], R[u][1]);
        swap(S[u][0], S[u][1]);
    }
    
    void pushup(int u) {
        for (int i = 0; i < 2; i++) {
            S[u][i] = max(max(S[lson(u)][i], S[rson(u)][i]), R[lson(u)][i] + L[rson(u)][i]);
            L[u][i] = L[lson(u)][i] + (L[lson(u)][i] == rc[lson(u)] - lc[lson(u)] + 1 ? L[rson(u)][i] : 0);
            R[u][i] = R[rson(u)][i] + (R[rson(u)][i] == rc[rson(u)] - lc[rson(u)] + 1 ? R[lson(u)][i] : 0);
        }
    }
    
    void pushdown (int u) {
        if (filp[u]) {
            maintain(lson(u));
            maintain(rson(u));
            filp[u] = 0;
        }
    }
    
    void build (int u, int l, int r) {
        lc[u] = l;
        rc[u] = r;
        filp[u] = 0;
    
        if (l == r) {
            int d = a[l];
            L[u][d] = R[u][d] = S[u][d] = 1;
            L[u][d^1] = R[u][d^1] = S[u][d^1] = 0;
            return ;
        }
    
        int mid = (l + r) / 2;
        build(lson(u), l, mid);
        build(rson(u), mid+1, r);
        pushup(u);
    }
    
    void modify (int u, int l, int r) {
        if (l <= lc[u] && rc[u] <= r) {
            maintain(u);
            return;
        }
    
        pushdown(u);
        int mid = (lc[u] + rc[u]) / 2;
        if (l <= mid)
            modify(lson(u), l, r);
        if (r > mid)
            modify(rson(u), l, r);
        pushup(u);
    }
    
    int query (int u, int l, int r) {
        if (l <= lc[u] && rc[u] <= r)
            return S[u][1];
    
        pushdown(u);
        int mid = (lc[u] + rc[u]) / 2, ret;
        if (r <= mid)
            ret = query(lson(u), l, r);
        else if (l > mid)
            ret = query(rson(u), l, r);
        else {
            int ll = query(lson(u), l, r);
            int rr = query(rson(u), l, r);
    
            int a = min(L[rson(u)][1], r - mid);
            int b = min(R[lson(u)][1], mid - l + 1);
    
            ret = max( max(ll, rr), a + b);
        }
        pushup(u);
        return ret;
    }
    
    int main () {
        int x, l, r;
    
        while (scanf("%d", &N) == 1) {
            for (int i = 1; i <= N; i++)
                scanf("%d", &a[i]);
            build (1, 1, N);
    
            scanf("%d", &M);
            while (M--) {
                scanf("%d%d%d", &x, &l, &r);
                if (x)
                    modify(1, l, r);
                else
                    printf("%d
    ", query(1, l, r));
            }
        }
        return 0;
    }
  • 相关阅读:
    C# Log4.Net日志组件的应用系列(二)
    C# Log4.Net日志组件的应用系列(一)
    使用TFS+GIT实现分布式项目管理
    动软代码生成器使用教程
    SVN使用教程
    windows系统重装流程
    使用纯真IP库获取用户端地理位置信息
    使用扩展方法重写.NET底层架构
    使用单例模式创建模型仓储层的唯一调用
    使用SQL Delta.v5.1.1.98.破解版同步数据结构
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4059736.html
Copyright © 2020-2023  润新知