线段树的模板题,注意利用lazy标记
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <string>
#include <stack>
#define maxn 100000+5
#define LL long long
using namespace std;
LL a[maxn+5], s[(maxn<<2)+5], add[(maxn<<2)+5];
void build(int o, int l, int r){
if(l == r) s[o] = a[l];
else{
int m = l + ((r-l)/2);
build(o*2, l, m);
build(o*2+1, m+1, r);
s[o] = s[o*2] + s[o*2+1];
}
}
void pushdown(int o, int l, int r){
if(add[o]){
add[o<<1] += add[o];
add[(o<<1)|1] += add[o];
int m = l + ((r-l)>>1);
s[o<<1] += add[o]*(LL)(m-l+1);
s[(o<<1)|1] += add[o]*(LL)(r-m);
add[o] = 0;
}
}
void update(int o, int l, int r, int ql, int qr, LL addv){
if(ql <= l && qr >= r){
add[o] += addv;
s[o] += addv*(LL)(r-l+1);
return;
}
pushdown(o, l, r);
int m = l + (r-l)/2;
if(ql <= m) update(o*2, l, m, ql, qr, addv);
if(qr >= m+1) update(o*2+1, m+1, r, ql, qr, addv);
s[o]=s[o<<1]+s[o<<1|1];
}
LL query(int o, int l, int r, int ql, int qr){
if(ql <= l && qr >= r) return s[o];
pushdown(o, l, r);
int m = l+(r-l)/2;
LL ans = 0;
if(ql <= m) ans += query(o*2, l, m, ql, qr);
if(qr >= m+1) ans += query(o*2+1, m+1, r, ql, qr);
return ans;
}
int main()
{
//freopen("ztest.txt","r",stdin);
memset(add, 0, sizeof(add));
int m, n;
while(scanf("%d%d", &m, &n) == 2){
memset(add, 0, sizeof(add));
for(int i = 0; i < m; i++)
scanf("%I64d", &a[i+1]);
build(1, 1, m);
for(int i = 0; i < n; i++){
char c;
cin >> c;
if(c == 'Q'){
int r, l;
scanf("%d%d", &l, &r);
printf("%lld\n",query(1, 1, m, l, r));
}
else{
int r, l;
LL a;
scanf("%d%d%lld", &l, &r, &a);
update(1, 1, m, l, r, a);
}
}
}
return 0;
}