如果你 60pts (WA:#7~#10).

P1253 扶苏的问题

OrangeRainee @ 2024-02-05 15:37:15

#include <bits/stdc++.h>

using namespace std;

const int maxn = 5e6 + 5;

using ll = long long;

struct SegmentTree {
    ll l, r;
    ll dat;
    ll tag_add;
    ll tag_cov;
    #define l(p) tree[p].l
    #define r(p) tree[p].r
    #define dat(p) tree[p].dat
    #define add(p) tree[p].tag_add
    #define cov(p) tree[p].tag_cov
} tree[maxn << 2];

ll a[maxn];

template <typename T> 
T read() {
    T x = 0, w = 1;
    char ch = 0;
    while (ch < '0' || ch > '9') {
        if (ch == '-')
            w = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = (x << 3) + (x << 1) + (ch - '0');
        ch = getchar();
    }
    return x * w;
}

ll n, m;

#define none (-1145141919810)

#define lson(p) (p << 1)
#define rson(p) (p << 1 | 1)

#define m(l, r) ((l + r) >> 1)

void pushup(ll now) {
    dat(now) = max(dat(lson(now)), dat(rson(now)));
    return;
}

void build(ll now, ll l, ll r) {
    l(now) = l;
    r(now) = r;
    add(now) = 0;
    cov(now) = none;
    if (l == r) {
        dat(now) = a[l];
        return;
    }
    ll mid = m(l, r);
    build(lson(now), l, mid);
    build(rson(now), mid + 1, r);
    pushup(now);
}

void spread_cov(ll now) {
    if (cov(now) != none) {
        cov(lson(now)) = cov(rson(now)) = cov(now);
        add(lson(now)) = add(rson(now)) = add(now) = 0;
        dat(lson(now)) = dat(rson(now)) = cov(now);
        cov(now) = none;
    }
    return;
}

void spread_add(ll now) {
    if (add(now)) {
        add(lson(now)) += add(now);
        add(rson(now)) += add(now);
        dat(lson(now)) += add(now);
        dat(rson(now)) += add(now);
        add(now) = 0;
    }
    return;
}

void spread(ll now) {
    spread_cov(now);
    spread_add(now);
    return;
}

void change(ll now, ll l, ll r, ll val) {
    if (l(now) >= l && r(now) <= r) {
        dat(now) = val;
        add(now) = 0;
        cov(now) = val;
        return;
    }
    spread(now);
    ll mid = m(l(now), r(now));
    if (l <= mid)
        change(lson(now), l, r, val);
    if (r > mid)
        change(rson(now), l, r, val);
    pushup(now);
}

void increase(ll now, ll l, ll r, ll val) {
    if (l(now) >= l && r(now) <= r) {
        if (cov(now) != none)
            cov(now) += val;
        else
            add(now) += val;
        dat(now) += val;
        return;
    }
    spread(now);
    ll mid = m(l(now), r(now));
    if (l <= mid)
        increase(lson(now), l, r, val);
    if (r > mid)
        increase(rson(now), l, r, val);
    pushup(now);
}

ll ask(ll now, ll l, ll r) {
    if (l(now) >= l && r(now) <= r) {
        return dat(now);
    }
    spread(now);
    ll mid = m(l(now), r(now));
    ll res = -1e18;
    if (l <= mid)
        res = max(res, ask(lson(now), l, r));
    if (r > mid)
        res = max(res, ask(rson(now), l, r));
    return res;
}

int main() {
    n = read<ll>();
    m = read<ll>();
    for (int i = 1; i <= n; ++i)
        a[i] = read<ll>();
    build(1, 1, n);
    for (int i = 1; i <= m; ++i) {
        ll op;
        ll l, r;
        op = read<ll>();
        l = read<ll>();
        r = read<ll>();
        if (op == 1) {
            ll x;
            x = read<ll>();
            change(1, l, r, x);
        }
        else if (op == 2) {
            ll x;
            x =  read<ll>();
            increase(1, l, r, x);
        }
        else {
            printf("%lld\n", ask(1, l, r));
        }
    }
    return 0;
}

此份代码错在第 72spread_cov。 下传覆盖标记时要清空左右儿子的增加标记,而不要顺便清空本身的增加标记。 具体来说,就是把第 72 行改为:

add(lson(now)) = add(rson(now)) = 0;

by huanxiel @ 2024-02-25 23:51:29

非常感谢


by doubleans @ 2024-03-20 11:51:30

非常好提醒,使我的代码AC,爱来自修了半天BUG的笨蛋


by Arrtan_73 @ 2024-04-06 08:41:06

膜拜Orz%%%%%%%%%,使我的代码AC到飞起


|