线段树lazy标记。正在看splay,碰到顺便复习下。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
using namespace std;
#define inf 1 << 29
#define N 100005
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
typedef long long LL;
LL a[N << 2], lz[N << 2];
void pushdown(int l, int r, int rt){
if(lz[rt]){
int m = (l + r) >> 1;
lz[rt << 1] += lz[rt];
lz[rt << 1 | 1] += lz[rt];
a[rt << 1] += lz[rt] * (m - l + 1);
a[rt << 1 | 1] += lz[rt] * (r - m);
lz[rt] = 0;
}
}
void pushup(int rt){
a[rt] = a[rt << 1] + a[rt << 1 | 1];
}
void build(int l, int r, int rt){
a[rt] = 0;
lz[rt] = 0;
if(l == r)return ;
int m = (l + r) >> 1;
build(lson);
build(rson);
}
LL query(int L, int R, int l, int r, int rt){
if(L <= l && r <= R){
return a[rt];
}
pushdown(l, r, rt);
int m = (l + r) >> 1;
LL ans = 0;
if(L <= m)ans += query(L, R, lson);
if(R > m)ans += query(L, R, rson);
return ans;
}
void update(int L, int R, int val, int l, int r, int rt){
if(L <= l && r <= R){
lz[rt] += val;
a[rt] += (LL)val * (r - l + 1);
return ;
}
pushdown(l, r, rt);
int m = (l + r) >> 1;
if(L <= m)update(L, R, val, lson);
if(R > m)update(L, R, val, rson);
pushup(rt);
}
int main(){
int n, q;
int x;
while(scanf("%d%d", &n, &q) != EOF){
build(1, n, 1);
for(int i = 0; i < n; i++){
scanf("%d", &x);
update(i + 1, i + 1, x, 1, n, 1);
}
char b[20];
int L, R, val;
for(int i = 0; i < q; i++){
scanf("%s", b);
if(b[0] == 'Q'){
scanf("%d%d", &L, &R);
printf("%I64d\n", query(L, R, 1, n, 1));
}
else {
scanf("%d%d%d", &L, &R, &val);
update(L, R, val, 1, n, 1);
}
}
}
return 0;
}