You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

102 lines
2.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// 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;
}