zoukankan      html  css  js  c++  java
  • bzoj 1858 线段树

    思路:很明显的线段树,随便搞搞lazy标记,维护一下区间最长的1。

    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PII pair<int, int>
    #define y1 skldjfskldjg
    #define y2 skldfjsklejg
    using namespace std;
    
    const int N = 1e5 + 7;
    const int M = 5e5 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1000000007;
    
    int n, m, lazy[N << 2];
    struct info {
        int m, l, r, s, w;
        info(){};
        info(int _m, int _l, int _r, int _s, int _w) {
            m = _m; w = _w;
            l = _l; r = _r;
            s = _s;
        }
    
        info operator + (const info &t) const {
            return info(max(max(m,t.m),r+t.l),l+(l==w)*t.l,t.r+(t.r==t.w)*r,s+t.s,w+t.w);
        }
    
        void change(int type) {
            if(!type) m = l = r = s = 0;
            else m = l = r = s = w;
        }
    } a[N << 2], b[N << 2];
    
    void pushdown(int rt, int l = 0, int r = 0) {
        if(!lazy[rt]) return;
        if(lazy[rt] == 1) {
            swap(a[rt << 1], b[rt << 1]);
            swap(a[rt << 1 | 1], b[rt << 1 | 1]);
            lazy[rt << 1] ^= 1;
            lazy[rt << 1 | 1] ^= 1;
        } else {
            int c = lazy[rt] - 2;
            a[rt << 1].change(c); b[rt << 1].change(c^1);
            a[rt << 1 | 1].change(c); b[rt << 1 | 1].change(c^1);
            lazy[rt << 1] = lazy[rt << 1 | 1] = lazy[rt];
        }
        lazy[rt] = 0;
    }
    
    void build(int l, int r, int rt) {
        if(l == r) {
            a[rt].w = b[rt].w = 1;
            int x; scanf("%d", &x);
            a[rt].change(x);
            b[rt].change(x^1);
            return;
        }
        int mid = l + r >> 1;
        build(l, mid, rt << 1);
        build(mid + 1, r, rt << 1 | 1);
        a[rt] = a[rt << 1] + a[rt << 1 | 1];
        b[rt] = b[rt << 1] + b[rt << 1 | 1];
    }
    
    void update(int L, int R, int c, int l, int r, int rt) {
        if(l >= L && r <= R) {
            if(c == 1) {
                swap(a[rt], b[rt]);
                lazy[rt] ^= 1;
            } else {
                a[rt].change(c-2);
                b[rt].change((c-2)^1);
                lazy[rt] = c;
            }
            return;
        }
        int mid = l + r >> 1;
        pushdown(rt, l, r);
        if(L <= mid) update(L, R, c, l, mid, rt << 1);
        if(R > mid) update(L, R, c, mid + 1, r, rt << 1 | 1);
        a[rt] = a[rt << 1] + a[rt << 1 | 1];
        b[rt] = b[rt << 1] + b[rt << 1 | 1];
    }
    
    info query(int L, int R, int l, int r, int rt) {
        if(l >= L && r <= R) return a[rt];
        int mid = l + r >> 1;
        pushdown(rt);
        if(R <= mid) return query(L, R, l, mid, rt << 1);
        if(L > mid) return query(L, R, mid + 1, r, rt << 1 | 1);
        return query(L, R, l, mid, rt << 1) + query(L, R, mid + 1, r, rt << 1 | 1);
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        build(1, n, 1);
        while(m--) {
            int op, L, R;
            scanf("%d%d%d", &op, &L, &R);
            L++; R++;
            if(op == 0) {
                update(L, R, 2, 1, n, 1);
            } else if(op == 1) {
                update(L, R, 3, 1, n, 1);
            } else if(op == 2) {
                update(L, R, 1, 1, n, 1);
            } else if(op == 3) {
                printf("%d
    ", query(L, R, 1, n, 1).s);
            } else {
                printf("%d
    ", query(L, R, 1, n, 1).m);
            }
        }
        return 0;
    }
    
    /*
       10 10
       0 0 0 1 1 0 1 0 1 1
       1 0 2
       2 2 2
    */
  • 相关阅读:
    Github简单使用
    软件架构
    软件架构
    软件架构
    VB.net 捕获项目全局异常
    C#里面的三种定时计时器:TIMER
    深入分析委托与事件
    C#预处理器指令
    C# 实现透明可移动窗体
    多元一次方程解法 C++
  • 原文地址:https://www.cnblogs.com/CJLHY/p/9589613.html
Copyright © 2011-2022 走看看