zoukankan      html  css  js  c++  java
  • BZOJ1858 [Scoi2010]序列操作(线段树)

    题目链接 [Scoi2010]序列操作

    考验代码能力的一道好题。

    思想还是很简单的(直接上线段树),但是比较难写。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define REP(i,n)                for(int i(0); i <  (n); ++i)
    #define rep(i,a,b)              for(int i(a); i <= (b); ++i)
    #define dec(i,a,b)              for(int i(a); i >= (b); --i)
    #define for_edge(i,x)           for(int i = H[x]; i; i = X[i])
    
    #define LL      long long
    #define ULL     unsigned long long
    #define MP      make_pair
    #define PB      push_back
    #define FI      first
    #define SE      second
    #define INF     1 << 30
    
    const int N     =    200000      +       10;
    const int M     =    10000       +       10;
    const int Q     =    1000        +       10;
    const int A     =    30          +       1;
    
    struct segTree{
        int len;
        int maxn[2], lmax[2], rmax[2], sum[2];
    } segtree[N << 2];
    
    int a[N], de_cover[N << 2], de_turn[N << 2];
    int n, m, op, x, y;
    
    segTree update(segTree x, segTree y){
        segTree ans;
        ans.len = x.len + y.len;
        rep(i, 0, 1){
            ans.sum[i] = x.sum[i] + y.sum[i];
            ans.lmax[i] = (x.lmax[i] == x.len ? x.len + y.lmax[i] : x.lmax[i]);
            ans.rmax[i] = (y.rmax[i] == y.len ? x.rmax[i] + y.len : y.rmax[i]);
            ans.maxn[i] = max(max(x.maxn[i], y.maxn[i]), max(ans.lmax[i], ans.rmax[i]));
            ans.maxn[i] = max(ans.maxn[i], x.rmax[i] + y.lmax[i]);
        }
    
        return ans;
    }
    
    
    void build(int i, int l, int r){
        if (l == r){
            int z = a[l];
            segtree[i].len = segtree[i].sum[z] = segtree[i].lmax[z] = segtree[i].rmax[z] = segtree[i].maxn[z] = 1;
            segtree[i].sum[z ^ 1] = segtree[i].lmax[z ^ 1] = segtree[i].rmax[z ^ 1] = segtree[i].maxn[z ^ 1] = 0;
            de_cover[i] = -1, de_turn[i] = 0;
            return ;
        }
    
        int mid = (l + r) >> 1;
        build(i << 1, l, mid);
        build(i << 1 | 1, mid + 1, r);
        segtree[i] = update(segtree[i << 1], segtree[i << 1 | 1]);
        de_cover[i] = -1, de_turn[i] = 0;
    }
    
    void paint_cover(int i, int z){
        de_cover[i] = z;
        de_turn[i] = 0;
        segtree[i].sum[z] = segtree[i].lmax[z] = segtree[i].rmax[z] = segtree[i].maxn[z] = segtree[i].len;
        segtree[i].sum[z ^ 1] = segtree[i].lmax[z ^ 1] = segtree[i].rmax[z ^ 1] = segtree[i].maxn[z ^ 1] = 0;
    }
    
    void paint_turn(int i, int z){
        if (z != -1){
            de_cover[i] ^= 1;
            segtree[i].sum[z] = segtree[i].lmax[z] = segtree[i].rmax[z] = segtree[i].maxn[z] = 0;
            segtree[i].sum[z ^ 1] = segtree[i].lmax[z ^ 1] = segtree[i].rmax[z ^ 1] = segtree[i].maxn[z ^ 1] = segtree[i].len;
        }
        else{
            de_turn[i] ^= 1;
            swap(segtree[i].sum[0], segtree[i].sum[1]);
            swap(segtree[i].lmax[0], segtree[i].lmax[1]);
            swap(segtree[i].rmax[0], segtree[i].rmax[1]);
            swap(segtree[i].maxn[0], segtree[i].maxn[1]);
        }
    }
    
    void pushdown(int i){
        if (de_cover[i] != -1){
            paint_cover(i << 1, de_cover[i]);
            paint_cover(i << 1 | 1, de_cover[i]);
            de_cover[i] = -1;
        }
        if (de_turn[i]){
            paint_turn(i << 1, de_cover[i << 1]);
            paint_turn(i << 1 | 1, de_cover[i << 1 | 1]);
            de_turn[i] = 0;
        }
    }
    
    void insert_cover(int i, int l, int r, int x, int y, int z){
        if (x <= l && y >= r){
            paint_cover(i, z);
            return ;
        }
    
        pushdown(i);
        int mid = (l + r) >> 1;
        if (x <= mid) insert_cover(i << 1, l, mid, x, y, z);
        if (y > mid) insert_cover(i << 1 | 1, mid + 1, r, x, y, z);
        segtree[i] = update(segtree[i << 1], segtree[i << 1 | 1]);
    }
    
    void insert_turn(int i, int l, int r, int x, int y){
        if (x <= l && y >= r){
            paint_turn(i, de_cover[i]);
            return ;
        }
    
        pushdown(i);
        int mid = (l + r) >> 1;
        if (x <= mid) insert_turn(i << 1, l, mid, x, y);
        if (y > mid) insert_turn(i << 1 | 1, mid + 1, r, x, y);
        segtree[i] = update(segtree[i << 1], segtree[i << 1 | 1]);
    }
    
    int query_sum(int i, int l, int r, int x, int y){
        int sum = 0;
        if (x <= l && y >= r){ return segtree[i].sum[1];}
        int mid = (l + r) >> 1;
        pushdown(i);
        if (x <= mid) sum += query_sum(i << 1, l, mid, x, y);
        if (y > mid) sum += query_sum(i << 1 | 1, mid + 1, r, x, y);
        return sum;
    }
    
    segTree query_con(int i, int l ,int r, int x, int y){
        segTree ans1, ans2;
        bool f1 = false, f2 = false;
        if (x <= l && y >= r) return segtree[i];
        pushdown(i);
    
        int mid = (l + r) >> 1;
        if (x <= mid) ans1 = query_con(i << 1, l, mid, x, y), f1 = true;
        if (y > mid) ans2 = query_con(i << 1 | 1, mid + 1, r, x, y), f2 = true;
        if (f1 && f2) return update(ans1, ans2);
        else return f1 ? ans1 : ans2;
    }
    
    
    
    int main(){
    
        scanf("%d%d", &n, &m);
        rep(i, 1, n) scanf("%d", a + i);
        build(1, 1, n);
        while (m--){
            scanf("%d%d%d", &op, &x, &y);
            ++x, ++y;
            if (op == 0) insert_cover(1, 1, n, x, y, 0);
            if (op == 1) insert_cover(1, 1, n, x, y, 1);
            if (op == 2) insert_turn(1, 1, n, x, y);
            if (op == 3) printf("%d
    ", query_sum(1, 1, n, x, y));
            if (op == 4) printf("%d
    ", query_con(1, 1, n, x, y).maxn[1]);
        }
    
        return 0;
    
    }
    
  • 相关阅读:
    注册页面
    JDBC操作MySQL数据
    音乐播放页面控制
    mysql知识点
    国内第一篇详细讲解hadoop2的automatic HA+Federation+Yarn配置的教程
    让自己变得更有钱
    看视频也能拿到月薪1万
    超人学院二期学员分享hadoop工作经验
    2013年吴超的个人总结
    国内最全最详细的hadoop2.2.0集群的MapReduce的最简单配置
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/6695071.html
Copyright © 2011-2022 走看看