萌新线段树 hack 数据过了,普通数据一个没过求调
查看原帖
萌新线段树 hack 数据过了,普通数据一个没过求调
610557
shinzanmonoszm 妹妹楼主2023/1/19 10:49
#include<iostream>
#include<algorithm>
const int sz = 1e5 + 10;
int arr[sz];
struct ST {
    struct node {
        int sum1, maxs1, maxl1, maxr1, sum0, maxs0, maxl0, maxr0;
        node operator+(const node &a) const {
            return node {
                sum1 + a.sum1,
                std::max(std::max(maxs1, a.maxs1), maxr1 + a.maxl1),
                maxl1 + (sum0 == 0) * a.maxl1,
                (a.sum0 == 0) * maxr1 + a.maxr1,
                sum0 + a.sum0,
                std::max(std::max(maxs0, a.maxs0), maxr0 + a.maxl0),
                maxl0 + (sum1 == 0) * a.maxl0,
                (a.sum1 == 0) * maxr0 + a.maxr0,
            };
        }
    } tree[sz << 2];
    bool iscov[sz << 2], isreverse[sz << 2];
    int cov[sz << 2];
    void operationAssign(int p, int ln, int rn, int val) {
        int l = rn - ln + 1;
        isreverse[p] = 0;
        cov[p] = val, iscov[p] = 1;
        if (val == 0) 
            tree[p] = {0, 0, 0, 0, l, l, l, l};
        else tree[p] = {l, l, l, l, 0, 0, 0, 0};
    }
    void operationReverse(int p) {
        if (iscov[p]) return cov[p] ^= 1, void();
        std::swap(tree[p].sum0, tree[p].sum1);
        std::swap(tree[p].maxs0, tree[p].maxs1);
        std::swap(tree[p].maxl0, tree[p].maxl1);
        std::swap(tree[p].maxr0, tree[p].maxr1);
        isreverse[p] ^= 1;
    }
    void pushdown(int p, int ln, int rn) {
        if (iscov[p]) {
            int mid = ln + rn >> 1;
            operationAssign(p << 1, ln, mid, cov[p]);
            operationAssign(p << 1 | 1, mid + 1, rn, cov[p]);
            iscov[p] = 0;
        }
        if (isreverse[p]) 
            operationReverse(p << 1), operationReverse(p << 1 | 1), isreverse[p] = 0;
    }
    void build(int p, int ln, int rn) {
        if (ln == rn) 
            return tree[p] = node{arr[ln] == 1, arr[ln] == 1, arr[ln] == 1, arr[ln] == 1,
            arr[ln] == 0, arr[ln] == 0, arr[ln] == 0, arr[ln] == 0}, void();
        int mid = ln + rn >> 1;
        build(p << 1, ln, mid);
        build(p << 1 | 1, mid + 1, rn);
        tree[p] = tree[p << 1] + tree[p << 1 | 1];
    }
    void assign(int p, int ln, int rn, int l, int r, int val) {
        if (ln >= l && rn <= r) return operationAssign(p, ln, rn, val);
        if (ln > r || rn < l) return;
        int mid = ln + rn >> 1;
        pushdown(p, ln, rn);
        assign(p << 1, ln, mid, l, r, val);
        assign(p << 1 | 1, mid + 1, rn, l, r, val);
        tree[p] = tree[p << 1] + tree[p << 1 | 1];
    }
    void reverse(int p, int ln, int rn, int l, int r) {
        if (ln >= l && rn <= r) return operationReverse(p);
        if (ln > r || rn < l) return;
        int mid = ln + rn >> 1;
        pushdown(p, ln, rn);
        reverse(p << 1, ln, mid, l, r);
        reverse(p << 1 | 1, mid + 1, rn, l, r);
        tree[p] = tree[p << 1] + tree[p << 1 | 1];
    }
    node query(int p, int ln, int rn, int l, int r) {
        if (ln >= l && rn <= r) return tree[p];
        if (ln > r || rn < l) return node{0, 0, 0, 0, 0, 0, 0, 0};
        int mid = ln + rn >> 1;
        pushdown(p, ln, rn);
        node res = node{0, 0, 0, 0, 0, 0, 0, 0};
        res = res + query(p << 1, ln, mid, l, r);
        res = res + query(p << 1 | 1, mid + 1, rn, l, r);
        return res;
    }
} st;
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int n, m;
    std::cin >> n >> m;
    for (int i = 1; i <= n; i++) std::cin >> arr[i];
    st.build(1, 1, n);
    while (m--) {
        int op, l, r;
        std::cin >> op >> l >> r;
        l++, r++;
        if (op == 0) st.assign(1, 1, n, l, r, 0);
        if (op == 1) st.assign(1, 1, n, l, r, 1);
        if (op == 2) st.reverse(1, 1, n, l, r);
        if (op == 3) std::cout << st.query(1, 1, n, l, r).sum1 << "\n";
        if (op == 4) std::cout << st.query(1, 1, n, l, r).maxs1 << "\n";
    }
    return 0;
}
2023/1/19 10:49
加载中...