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