求助:不开O2 AC,开O2 20pts

P2572 [SCOI2010] 序列操作

heptari @ 2022-11-11 11:11:05

代码:

#include <bits/stdc++.h>
using namespace std;

#define int long long

#define MAXN 100005
#define pushup(now) tree[now] = tree[now<<1] + tree[now<<1|1]

struct Tag {
    int g1, g2;
    Tag(int G1 = -1, int G2 = 0): g1(G1), g2(G2) {} //g1: 平推  g2:取反

    Tag operator + (Tag y) {
        if (g1 == -1 && g2 == 0) return y;
        if (y.g1 == -1 && y.g2 == 0) return *this;

        if (y.g1 != -1 && y.g2 == 0) return y;
        if (y.g1 == -1) {
            //g1 == 0 && g2 == 0 : 0
            //g1 == 1 && g2 == 0 : 1
            //g1 == 0 && g2 == 1 : 1
            //g1 == 1 && g2 == 1 : 1
            g2 ^= y.g2;
            return *this;
        }
    }
};

struct node {
    int l, r, len, sum0, sum1, fi0, fi1, la0, la1, len0, len1;
    Tag tag;
    node operator + (node x) {
        node t;
        t.l = l;
        t.r = x.r;
        t.len = len + x.len;
        t.sum0 = sum0 + x.sum0;
        t.sum1 = sum1 + x.sum1;

        if (len == fi0) t.fi0 = fi0 + x.fi0;
        else t.fi0 = fi0;

        if (len == fi1) t.fi1 = fi1 + x.fi1;
        else t.fi1 = fi1;

        if (x.la0 == x.len) t.la0 = la0 + x.len;
        else t.la0 = x.la0;

        if (x.la1 == x.len) t.la1 = la1 + x.len;
        else t.la1 = x.la1;

        t.len0 = max(len0, max(x.len0, (la0 + x.fi0)));
        t.len1 = max(len1, max(x.len1, (la1 + x.fi1)));

        t.tag = Tag();

        return t;
    }

    void operator += (Tag x) {
        if (x.g1 == 0) {
            fi0 = la0 = len0 = sum0 = len;
            fi1 = la1 = len1 = sum1 = 0;
        }
        if (x.g1 == 1) {
            fi0 = la0 = len0 = sum0 = 0;
            fi1 = la1 = len1 = sum1 = len;
        }
        if (x.g2 == 1) {
            swap(fi0, fi1);
            swap(la0, la1);
            swap(len0, len1);
            swap(sum0, sum1);
        }

        tag = tag + x;
    }
} tree[MAXN << 2];

void pushdown(int now) {
    tree[now << 1] += tree[now].tag;
    tree[now << 1 | 1] += tree[now].tag;

    tree[now].tag = Tag();
}

int arr[MAXN];

void build(int l, int r, int now) {
    if (l == r) {
        tree[now].l = l;
        tree[now].r = r;
        tree[now].len = 1;
        if (arr[l] == 1) {
            tree[now].fi0 = tree[now].la0 = tree[now].len0 = tree[now].sum0 = 0;
            tree[now].fi1 = tree[now].la1 = tree[now].len1 = tree[now].sum1 = 1;
        } else {
            tree[now].fi0 = tree[now].la0 = tree[now].len0 = tree[now].sum0 = 1;
            tree[now].fi1 = tree[now].la1 = tree[now].len1 = tree[now].sum1 = 0;
        }

        tree[now].tag = Tag();

        return;
    }
    int mid = (l + r) >> 1;
    build(l, mid, now << 1);
    build(mid + 1, r, now << 1 | 1);

    pushup(now);
}

void modify(int l, int r, Tag tag, int now) {
    if (tree[now].l != tree[now].r) pushdown(now);

    if (l <= tree[now].l && tree[now].r <= r) {
        tree[now] += tag;
        return;
    }

    int mid = (tree[now].l + tree[now].r) >> 1;
    if (l <= mid) modify(l, r, tag, now << 1);
    if (r > mid) modify(l, r, tag, now << 1 | 1);

    pushup(now);
}

node query(int l, int r, int now) {
    if (tree[now].l != tree[now].r) pushdown(now);

    if (l <= tree[now].l && tree[now].r <= r) return tree[now];

    int mid = (tree[now].l + tree[now].r) >> 1;
    if (l <= mid && r > mid) return query(l, r, now << 1) + query(l, r, now << 1 | 1);
    if (l <= mid) return query(l, r, now << 1);
    if (r > mid) return query(l, r, now << 1 | 1);
}

signed main() {
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) cin >> arr[i];
    build(1, n, 1);
    while (m--) {
        int opt, l, r;
        cin >> opt >> l >> r;
        if (opt == 0) modify(l + 1, r + 1, {0, 0}, 1);
        if (opt == 1) modify(l + 1, r + 1, {1, 0}, 1);
        if (opt == 2) modify(l + 1, r + 1, {-1, 1}, 1);
        if (opt == 3) cout << query(l + 1, r + 1, 1).sum1 << endl;
        if (opt == 4) cout << query(l + 1, r + 1, 1).len1 << endl;
    }
    return 0;
}

by w23c3c3 @ 2022-11-11 11:16:31

会不会 tag+tag 有可能没 return。
没仔细看代码。


by heptari @ 2022-11-11 11:18:31

@w23c3c3 return之后也是20(哭


by w23c3c3 @ 2022-11-11 11:27:40

但是应该就是 tag+tag 没 return 啊(


by w23c3c3 @ 2022-11-11 11:28:24

应该是 return y 你看看对不对。


by heptari @ 2022-11-11 11:29:32

@w23c3c3 对了~ 谢谢啦


|