Files
python/TangDou/AcWing/SegmentTree/ZKW/243.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

102 lines
2.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ZKW 变异模板解决AcWing 243
// https://codeforces.com/blog/entry/18051
// 普通树段树 323 ms 向上向下
// ZKW 线段树 192 ms 向下向上
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define LL long long
//快读
int read() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 3) + (x << 1) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
const int N = 1e5 + 10;
int n, h, m;
LL sum[N << 1], tag[N << 1];
void build() {
for (h = 1; 1 << h < n;) h++; //计算树高
for (int i = n + 1; i <= 2 * n; i++) sum[i] = read(); //叶子节点赋值
for (int i = n; i; i--) sum[i] = sum[i << 1] + sum[i << 1 | 1]; //统计信息更新
}
void add(int x, int val, int len) {
sum[x] += val * len;
if (x <= n) tag[x] += val; //如果不是是叶子才打标记
}
void pushup(int x) {
int len = 1;
while (x > 1) len <<= 1, x >>= 1, sum[x] = sum[x << 1] + sum[x << 1 | 1] + tag[x] * len;
//从下往上,儿子的值不一定正确,需要累上标记
}
void pushdown(int x) {
for (int i = h, len = 1 << (h - 1); i; i--, len >>= 1) { //从上到下len初始为1<<(h-1)
int y = x >> i;
if (tag[y]) { //下传标记
add(y << 1, tag[y], len), add(y << 1 | 1, tag[y], len);
tag[y] = 0;
}
}
}
void modify(int l, int r, int val) {
l += n, r += n;
int yl = l, yr = r;
for (int len = 1; l <= r; l = (l + 1) >> 1, r = (r - 1) >> 1, len <<= 1) { //从下往上,叶子节点len为1
if (l & 1) add(l, val, len);
if (r & 1 ^ 1) add(r, val, len);
}
pushup(yl), pushup(yr); //别忘了pushup
}
LL query(int l, int r) {
l += n, r += n;
pushdown(l), pushdown(r); //查询前要下传该区间标记
LL res = 0;
for (; l <= r; l = (l + 1) >> 1, r = (r - 1) >> 1) {
if (l & 1) res += sum[l];
if (r & 1 ^ 1) res += sum[r];
}
return res;
}
int main() {
//文件输入输出
#ifndef ONLINE_JUDGE
freopen("243.in", "r", stdin);
#endif
n = read(), m = read();
//构建线段树
build();
int x, y, k;
char op[2];
while (m--) {
scanf("%s", op);
x = read(), y = read();
if (op[0] == 'C') {
k = read();
modify(x, y, k);
} else
printf("%lld\n", query(x, y));
}
return 0;
}