이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
#define nl '\n'
template <typename T, typename L, typename F = std::plus<T>>
struct SegmentTree {
int n;
std::vector<T> tree;
std::vector<L> lazy;
SegmentTree(int _n) : n(_n), tree(2 * n - 1), lazy(2 * n - 1) {}
template <typename Vec>
void build(int x, int l, int r, const Vec& v) {
if (l == r - 1) {
tree[x] = T::from_value(v[l]);
return;
}
int m = (l + r) / 2, y = x + 1, z = x + (m - l) * 2;
build(y, l, m, v);
build(z, m, r, v);
tree[x] = F()(tree[y], tree[z]);
}
template <typename Vec>
SegmentTree(const Vec& v) : SegmentTree(static_cast<int>(v.size())) {
build(0, 0, n, v);
}
inline void apply(int x, const L& t) {
tree[x].apply(t);
lazy[x].apply(t);
}
inline void push(int x, int y, int z) {
apply(y, lazy[x]);
apply(z, lazy[x]);
lazy[x] = L();
}
inline void pull(int x, int y, int z) {
tree[x] = F()(tree[y], tree[z]);
}
void modify(int x, int l, int r, int p, const T& v) {
if (l == r - 1) {
tree[x] = v;
return;
}
int m = (l + r) / 2, y = x + 1, z = x + (m - l) * 2;
push(x, y, z);
if (p < m)
modify(y, l, m, p, v);
else
modify(z, m, r, p, v);
pull(x, y, z);
}
void range_apply(int x, int l, int r, int ql, int qr, const L& t) {
if (ql <= l && r <= qr) {
apply(x, t);
return;
}
int m = (l + r) / 2, y = x + 1, z = x + (m - l) * 2;
push(x, y, z);
if (m > ql) range_apply(y, l, m, ql, qr, t);
if (m < qr) range_apply(z, m, r, ql, qr, t);
pull(x, y, z);
}
T range_query(int x, int l, int r, int ql, int qr) {
if (ql <= l && r <= qr) {
return tree[x];
}
int m = (l + r) / 2, y = x + 1, z = x + (m - l) * 2;
push(x, y, z);
if (m <= ql) return range_query(z, m, r, ql, qr);
if (m >= qr) return range_query(y, l, m, ql, qr);
return F()(range_query(y, l, m, ql, qr), range_query(z, m, r, ql, qr));
}
inline void modify(int p, const T& v) {
assert(0 <= p && p < n);
modify(0, 0, n, p, v);
}
// NOTE: [l, r)
inline void range_apply(int l, int r, const L& t) {
assert(0 <= l && l < r && r <= n);
range_apply(0, 0, n, l, r, t);
}
// NOTE: [l, r)
inline T range_query(int l, int r) {
assert(0 <= l && l < r && r <= n);
return range_query(0, 0, n, l, r);
}
};
struct Tag {
int64_t x;
inline void apply(const Tag& t) {
x += t.x;
}
};
int S, T;
struct Info {
int64_t l, r;
int64_t delta;
// implement from_value<T> to allow build(vector<T>)
static Info from_value(int x) {
return {x, x, 0};
}
inline void apply(const Tag& t) {
l += t.x;
r += t.x;
}
friend Info operator+(const Info& l, const Info& r) {
int64_t ll = l.l;
int64_t rr = r.r;
int64_t delta = l.delta;
if (l.r < r.l) {
delta -= S * (r.l - l.r);
} else {
delta += T * (l.r - r.l);
}
delta += r.delta;
return {ll, rr, delta};
}
};
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int N, Q;
std::cin >> N >> Q >> S >> T;
std::vector<int> A(N + 1);
for (int i = 0; i <= N; i++) {
std::cin >> A[i];
}
SegmentTree<Info, Tag> tree(A);
while (Q--) {
int l, r, x;
std::cin >> l >> r >> x;
tree.range_apply(l, r + 1, {x});
std::cout << tree.range_query(0, N + 1).delta << nl;
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |