题解:P13825 线段树 1.5
Analysis
首先问题可以变成一个初始全
然后考虑这个对初始全
假设我们能把这个
我们只维护非
注意到这样的写法仍然创建了一些仅用于查询的(本身没被修改过,即值为
注意要开 unsiged long long。
Code
#include <bits/stdc++.h>
using ll = unsigned long long;
struct Node {
Node *ls, *rs;
int l, r;
ll val, tag;
Node(int L, int R) : l(L), r(R), val(0), tag(0) {
ls = rs = nullptr;
}
void pushup() { val = ls->val + rs->val; }
bool inRange(int L, int R) { return L <= l && r <= R; }
bool outRange(int L, int R) { return r < L || R < l; }
inline void makeTag(ll x) {
val += (r - l + 1) * x;
tag += x;
}
inline void pushdown() {
if (!ls) {
int mid = (l + r) >> 1;
ls = new Node(l, mid);
rs = new Node(mid + 1, r);
}
if (tag) {
ls->makeTag(tag);
rs->makeTag(tag);
tag = 0;
}
}
void upd(int L, int R, ll k) {
if (inRange(L, R)) {
makeTag(k);
} else if (!outRange(L, R)) {
pushdown();
ls->upd(L, R, k);
rs->upd(L, R, k);
pushup();
}
}
ll qry(int L, int R) {
if (inRange(L, R)) {
return val;
} else if (outRange(L, R)) {
return 0;
} else {
pushdown();
return ls->qry(L, R) + rs->qry(L, R);
}
}
};
int main() {
int n, q;
std::cin >> n >> q;
auto rot = new Node(1, n);
for (int op, l, r; q; --q) {
std::cin >> op >> l >> r;
if (op == 1) {
ll k;
std::cin >> k;
rot->upd(l, r, k);
} else {
std::println("{}", rot->qry(l, r) + [](ll L, ll R) -> ll {
return (R - L + 1) * (R + L) / 2;
}(l, r));
}
}
}