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;
}
此份代码错在第 72
行 spread_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到飞起