裸线段树...
#include <cstdio>
#include <cstring>
using namespace std;
struct Node {
int l,r;
long long sum,lazy;
Node *ls,*rs;
};
Node a[300100];
Node *p;
int n,q;
Node *maketree(int l,int r) {
Node *tmp=p++;
tmp->l=l;
tmp->r=r;
int t=(l+r)/2;
if (l!=t) tmp->ls=maketree(l,t);
else tmp->ls=&a[l];
if (r!=t+1) tmp->rs=maketree(t+1,r);
else tmp->rs=&a[r];
tmp->sum=tmp->ls->sum+tmp->rs->sum;
tmp->lazy=0;
//printf("%d %d %d\n",(int)(tmp-a),l,r);
return tmp;
}
long long get(Node *from,int l,int r) {
//printf("--%d %d %d\n",(int)(from-a),l,r);
if (from->lazy!=0) {
if (from->ls!=NULL) from->ls->lazy+=from->lazy;
if (from->rs!=NULL) from->rs->lazy+=from->lazy;
from->sum+=from->lazy*(from->r-from->l+1);
from->lazy=0;
}
if (from->l==l&&from->r==r) return from->sum;
int t=(from->l+from->r)/2;
if (r<=t) return get(from->ls,l,r);
if (l>t) return get(from->rs,l,r);
return get(from->ls,l,t)+get(from->rs,t+1,r);
}
void add(Node *from,int l,int r,int x) {
if (from->lazy!=0) {
if (from->ls!=NULL) from->ls->lazy+=from->lazy;
if (from->rs!=NULL) from->rs->lazy+=from->lazy;
from->sum+=from->lazy*(from->r-from->l+1);
from->lazy=0;
}
if (from->l==l&&from->r==r) from->lazy+=x;
else {
from->sum+=x*(r-l+1);
int t=(from->l+from->r)/2;
if (r<=t) add(from->ls,l,r,x);
else if (l>t) add(from->rs,l,r,x);
else {
add(from->ls,l,t,x);
add(from->rs,t+1,r,x);
}
}
}
int main() {
int i,x,y,z;
long long ans;
char c;
while (scanf("%d%d",&n,&q)!=EOF) {
for (i=1;i<=n;i++) {
scanf("%d",&x);
a[i].l=a[i].r=i;
a[i].ls=a[i].rs=NULL;
a[i].lazy=0;
a[i].sum=x;
}
p=&a[n+1];
maketree(1,n);
for (i=0;i<q;i++) {
scanf(" %c",&c);
if (c=='Q') {
scanf("%d%d",&x,&y);
ans=get(&a[n+1],x,y);
printf("%lld\n",ans);
} else {
scanf("%d%d%d",&x,&y,&z);
add(&a[n+1],x,y,z);
}
}
}
return 0;
}