能过样例,全WA求查错

P2572 [SCOI2010] 序列操作

yu__xuan @ 2020-08-12 06:49:13

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define MAXN 100001
#define lson now << 1
#define rson now << 1 | 1

int max(int a, int b) { return a > b ? a : b; }

int n, m;
struct Node {
    int l, r, w, lazy, tag;
    int lmax1, rmax1, maxx1;
    int lmax0, rmax0, maxx0;
}tree[MAXN << 2];

void pushup(int now) {
    tree[now].w = tree[lson].w + tree[rson].w;
    if (tree[lson].lmax1 == tree[lson].r - tree[lson].l + 1 && tree[rson].lmax1) tree[now].lmax1 = tree[lson].lmax1 + tree[rson].lmax1;
    else tree[now].lmax1 = tree[lson].lmax1;
    if (tree[rson].rmax1 == tree[rson].r - tree[rson].l + 1 && tree[lson].rmax1) tree[now].rmax1 = tree[lson].rmax1 + tree[rson].rmax1;
    else tree[now].rmax1 = tree[rson].rmax1;
    tree[now].maxx1 = max(tree[lson].maxx1, tree[rson].maxx1);
    if (tree[lson].rmax1 && tree[rson].lmax1) tree[now].maxx1 = max(tree[now].maxx1, tree[lson].rmax1 + tree[rson].lmax1);
    if (tree[lson].lmax0 == tree[lson].r - tree[lson].l + 1 && tree[rson].lmax0) tree[now].lmax0 = tree[lson].lmax0 + tree[rson].lmax0;
    else tree[now].lmax0 = tree[lson].lmax0;
    if (tree[rson].rmax0 == tree[rson].r - tree[rson].l + 1 && tree[lson].rmax0) tree[now].rmax0 = tree[lson].rmax0 + tree[rson].rmax0;
    else tree[now].rmax0 = tree[rson].rmax0;
    tree[now].maxx0 = max(tree[lson].maxx0, tree[rson].maxx0);
    if (tree[lson].rmax0 && tree[rson].lmax0) tree[now].maxx0 = max(tree[now].maxx0, tree[lson].rmax0 + tree[rson].lmax0);
}

void build(int l, int r, int now) {
    tree[now].lazy = -1, tree[now].l = l, tree[now].r = r;
    if (tree[now].l == tree[now].r) {
        scanf("%d", &tree[now].w);
        tree[now].lmax1 = tree[now].maxx1 = tree[now].rmax1 = tree[now].w;
        tree[now].lmax0 = tree[now].maxx0 = tree[now].rmax0 = tree[now].w ^ 1;
        return;
    }
    int mid = (tree[now].l + tree[now].r) >> 1;
    build(l, mid, lson), build(mid + 1, r, rson);
    pushup(now);
}

void pushdown(int now) {
    if (tree[now].l == tree[now].r) return;
    tree[lson].lazy = tree[rson].lazy = tree[now].lazy;
    tree[lson].w = (tree[lson].r - tree[lson].l + 1) * tree[now].lazy;
    tree[lson].maxx1 = tree[lson].lmax1 = tree[lson].rmax1 = tree[lson].w;
    tree[lson].maxx0 = tree[lson].lmax0 = tree[lson].rmax0 = (tree[lson].r - tree[lson].l + 1) - tree[lson].w;
    tree[rson].w = (tree[rson].r - tree[rson].l + 1) * tree[now].lazy;
    tree[rson].maxx1 = tree[rson].lmax1 = tree[rson].rmax1 = tree[rson].w;
    tree[rson].maxx0 = tree[rson].lmax0 = tree[rson].rmax0 = (tree[rson].r - tree[rson].l + 1) - tree[rson].w;
    tree[now].lazy = -1;
}

void pushdown1(int now) {
    if (tree[now].l == tree[now].r) return;
    tree[lson].tag = tree[rson].tag = 1;
    tree[lson].w = (tree[lson].r - tree[lson].l + 1) - tree[lson].w;
    int temp = tree[lson].maxx1; tree[lson].maxx1 = tree[lson].maxx0, tree[lson].maxx0 = temp;
    temp = tree[lson].lmax1, tree[lson].lmax1 = tree[lson].lmax0, tree[lson].lmax0 = temp;
    temp = tree[lson].rmax1, tree[lson].rmax1 = tree[lson].rmax0, tree[lson].rmax0 = temp;
    tree[rson].w = (tree[rson].r - tree[rson].l + 1) - tree[rson].w;
    temp = tree[rson].maxx1, tree[rson].maxx1 = tree[rson].maxx0, tree[rson].maxx0 = temp;
    temp = tree[rson].lmax1, tree[rson].lmax1 = tree[rson].lmax0, tree[rson].lmax0 = temp;
    temp = tree[rson].rmax1, tree[rson].rmax1 = tree[rson].rmax0, tree[rson].rmax0 = temp;
    tree[now].tag = 0;
}

void update1(int x, int y, int k, int now) {
    if (tree[now].l >= x && tree[now].r <= y) {
        tree[now].w = (tree[now].r - tree[now].l + 1) * k;
        tree[now].maxx1 = tree[now].lmax1 = tree[now].rmax1 = tree[now].w;
        tree[now].maxx0 = tree[now].lmax0 = tree[now].rmax0 = (tree[now].r - tree[now].l + 1) - tree[now].w;
        tree[now].tag = 0, tree[now].lazy = k; return;
    }
    if (tree[now].tag) pushdown1(now);
    if (tree[now].lazy != -1) pushdown(now);
    int mid = (tree[now].l + tree[now].r) >> 1;
    if (x <= mid) update1(x, y, k, lson);
    if (y > mid) update1(x, y, k, rson);
    pushup(now);
}

void update2(int x, int y, int now) {
    if (tree[now].l >= x && tree[now].r <= y) {
        tree[now].w = (tree[now].r - tree[now].l + 1) - tree[now].w;
        int temp = tree[now].maxx1; tree[now].maxx1 = tree[now].maxx0, tree[now].maxx0 = temp;
        temp = tree[now].lmax1, tree[now].lmax1 = tree[now].lmax0, tree[now].lmax0 = temp;
        temp = tree[now].rmax1, tree[now].rmax1 = tree[now].rmax0, tree[now].rmax0 = temp;
        if (tree[now].lazy != -1) tree[now].lazy ^= 1;
        else tree[now].tag = 1;
        return;
    }
    if (tree[now].tag) pushdown1(now);
    if (tree[now].lazy != -1) pushdown(now);
    int mid = (tree[now].l + tree[now].r) >> 1;
    if (x <= mid) update2(x, y, lson);
    if (y > mid) update2(x, y, rson);
    pushup(now);
}

int query1(int x, int y, int now) {
    if (tree[now].l >= x && tree[now].r <= y) return tree[now].w;
    if (tree[now].tag) pushdown1(now);
    if (tree[now].lazy != -1) pushdown(now);
    int mid = (tree[now].l + tree[now].r) >> 1, ans = 0;
    if (x <= mid) ans += query1(x, y, lson);
    if (y > mid) ans += query1(x, y, rson);
    return ans;
}

Node merge(Node left, Node right) {
    Node ans;
    ans.w = left.w + right.w;
    if (left.lmax1 == left.r - left.l + 1 && right.lmax1) ans.lmax1 = left.lmax1 + right.lmax1;
    else ans.lmax1 = left.lmax1;
    if (right.rmax1 == right.r - right.l + 1 && left.rmax1) ans.rmax1 = left.rmax1 + right.rmax1;
    else ans.rmax1 = right.rmax1;
    ans.maxx1 = max(left.maxx1, right.maxx1);
    if (left.rmax1 && right.lmax1) ans.maxx1 = max(ans.maxx1, left.rmax1 + right.lmax1);
    if (left.lmax0 == left.r - left.l + 1 && right.lmax0) ans.lmax0 = left.lmax0 + right.lmax0;
    else ans.lmax0 = left.lmax0;
    if (right.rmax0 == right.r - right.l + 1 && left.rmax0) ans.rmax0 = left.rmax0 + right.rmax0;
    else ans.rmax0 = right.rmax0;
    ans.maxx0 = max(left.maxx0, right.maxx0);
    if (left.rmax0 && right.lmax0) ans.maxx0 = max(ans.maxx0, left.rmax0 + right.lmax0);
    return ans;
}

Node query2(int x, int y, int now) {
    if (tree[now].l >= x && tree[now].r <= y) return tree[now];
    if (tree[now].tag) pushdown1(now);
    if (tree[now].lazy != -1) pushdown(now);
    int mid = (tree[now].l + tree[now].r) >> 1;
    if (x > mid) return query2(x, y, rson);
    else if (y <= mid) return query2(x, y, lson);
    else return merge(query2(x, y, lson), query2(x, y, rson));
}

int main() {
    scanf("%d %d", &n, &m);
    build(1, n, 1);
    for (int i = 1, opt, x, y; i <= m; ++i) {
        scanf("%d %d %d", &opt, &x, &y);
        ++x, ++y;
        if (opt == 0) update1(x, y, 0, 1);
        if (opt == 1) update1(x, y, 1, 1);
        if (opt == 2) update2(x, y, 1);
        if (opt == 3) printf("%d\n", query1(x, y, 1));
        if (opt == 4) printf("%d\n", query2(x, y, 1).maxx1);
    }
    return 0;
}

by xwmwr @ 2020-08-12 09:43:25

@yu__xuan 还在调吗, 我有点闲想练下调试


by yu__xuan @ 2020-08-12 09:48:35

@水比田昭寿 在调


by yu__xuan @ 2020-08-12 10:06:45

@水比田昭寿 下放区间取反,和区间取反的懒标那里有错误,改了之后过了一个点qwq


by xwmwr @ 2020-08-12 10:11:20

@yu__xuan 这个写法似乎很香


by yu__xuan @ 2020-08-12 10:11:23

@水比田昭寿 过了,就是区间取反的懒标处理有问题qwq


by xwmwr @ 2020-08-12 10:13:13

@yu__xuan 那我根勃去了


by yu__xuan @ 2020-08-12 10:14:12

@水比田昭寿 好,那我去点赞/cy


by guodong @ 2020-09-10 12:28:05


10 3 
1 1 1 1 0 1 0 1 0 1 
2 1 7 
4 7 9 
3 1 5

补一下(

|