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\n", query(L, R, 1, n, 1).s);
        } else {
            printf("%d\n", 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
*/

 

posted @ 2018-09-05 01:48  NotNight  阅读(126)  评论(0编辑  收藏  举报