输出 11 8 16,不知道哪里错了 /kk
#include <iostream>
using namespace std;
namespace Solution {
using LL = long long;
constexpr int N = 1e5 + 5, NODE = N << 2; // 线段树是完全二叉树,节点数 < 深度 * 4
int n;
LL a[N], tree[NODE], flag[NODE];
void dbg() {
cerr << "tree: ";
for (int i = 1; i < n * 2; ++i) cerr << tree[i] << ' ';
cerr << "\nflag: ";
for (int i = 1; i < n * 2; ++i) cerr << flag[i] << ' ';
cerr << '\n';
}
inline int left(int x) { return x << 1; }
inline int right(int x) { return (x << 1) + 1; }
void pushDown(int root, int l, int r) {
cerr << "push " << root << ' ' << l << ' ' << r << '\n';
if (!flag[root]) return;
tree[root] += flag[root] * (r - l + 1); // [l, r] 区间内都加了 flag[root]
if (l != r) { // 需要下发标记
flag[left(root)] += flag[root];
flag[right(root)] += flag[root];
}
flag[root] = 0;
}
inline void pushUp(int x) {
tree[x] = tree[left(x)] + tree[right(x)];
}
void build(int root, int l, int r) {
if (l == r) {
tree[root] = a[l];
} else {
int mid = (l + r) >> 1;
build(left(root), l, mid);
build(right(root), mid + 1, r);
pushUp(root);
}
}
void update(int l, int r, LL value, int root = 1, int start = 1, int end = n) {
cerr << "update " << l << '~' << r << ", " << value << ", " << root << ", " << start << '~' << end << '\n';
if (l <= start && r >= end) {
// @todo optimize
tree[root] += value * (end - start + 1);
flag[root] += value;
} else {
pushDown(root, start, end);
int mid = (start + end) >> 1;
if (l <= mid)
update(l, r, value, left(root), start, mid);
if (r > mid)
update(l, r, value, right(root), mid + 1, end);
pushUp(root);
}
dbg();
}
LL query(int l, int r, int root = 1, int start = 1, int end = n) {
cerr << "query\n";
if (l <= start && r >= end) return tree[root];
pushDown(root, start, end);
if (start == end) return tree[root];
int ans = 0, mid = (start + end) >> 1;
if (l <= mid) ans += query(l, r, left(root), start, mid);
if (r > mid) ans += query(l, r, right(root), mid + 1, end);
dbg();
return ans;
}
void solve() {
int m;
cin >> n >> m;
for (int i = 1; i <= n; ++i)
cin >> a[i];
build(1, 1, n);
while (m--) {
int op, x, y, k;
cin >> op >> x >> y;
switch (op) {
case 1:
cin >> k;
update(x, y, k);
break;
case 2:
cout << query(x, y) << '\n';
break;
}
cerr << '\n';
}
}
} // namespace Solution
int main() {
ios::sync_with_stdio(0);
cin.tie(nullptr);
Solution::solve();
return 0;
}
(祝各位 CSP 2024 rp++)