1 #include<stdio.h>
2 #define N 100010
3 struct node{
4 int l,r;
5 __int64 inc,sum;//注意要定义为__int64型
6 }tree[3*N];
7 int num[N];
8 void build(int l,int r,int i)//建立线段树
9 {
10 tree[i].l=l;
11 tree[i].r=r;
12 tree[i].inc=0;
13 if(l==r){
14 tree[i].sum=num[l];//叶子节点赋值
15 return;
16 }
17 int mid=(l+r)>>1;
18 build(l,mid,i<<1);
19 build(mid+1,r,(i<<1)+1);
20 tree[i].sum=tree[i<<1].sum+tree[(i<<1)+1].sum;//回归时给非叶子节点赋值
21 }
22 void update(int l,int r,int inc,int i)//l~r段的节点元素值增加inc
23 {
24 if(l==tree[i].l&&tree[i].r==r){//假如找到这段,则此节点inc域增加
25 tree[i].inc+=inc;
26 return;
27 }else{//否则说明此节点包括此段,则直接让其sum域这一段的增量
28 tree[i].sum+=(r-l+1)*inc;
29 }
30 int mid=(tree[i].l+tree[i].r)>>1;
31 if(r<=mid) update(l,r,inc,i<<1);
32 else if(l>mid) update(l,r,inc,(i<<1)+1);
33 else{
34 update(l,mid,inc,i<<1);
35 update(mid+1,r,inc,(i<<1)+1);
36 }
37 }
38 __int64 query(int l,int r,int i)//查询l~r段元素的和
39 {
40 __int64 sum=0;
41 if(l==tree[i].l&&tree[i].r==r){//找到此段直接加到sum上
42 sum+=tree[i].sum+(r-l+1)*tree[i].inc;
43 return sum;
44 }
45 if(tree[i].inc){//往下消除增量
46 int t=i<<1;
47 tree[t].inc+=tree[i].inc;
48 tree[t+1].inc+=tree[i].inc;
49 tree[i].sum+=(tree[i].r-tree[i].l+1)*tree[i].inc;
50 tree[i].inc=0;//记得置零
51 }
52 int mid=(tree[i].l+tree[i].r)>>1;
53 if(r<=mid) sum+=query(l,r,i<<1);
54 else if(l>mid) sum+=query(l,r,(i<<1)+1);
55 else{
56 sum+=query(l,mid,i<<1);
57 sum+=query(mid+1,r,(i<<1)+1);
58 }
59 return sum;
60 }
61 int main()
62 {
63 int i,a,b,n,inc,Q;
64 char c;
65 scanf("%d%d",&n,&Q);
66 for(i=1;i<=n;++i)
67 scanf("%d",&num[i]);
68 build(1,n,1);
69 while(Q--){
70 scanf("%*c%c%d%d",&c,&a,&b);
71 if(c=='Q') printf("%I64d\n",query(a,b,1));
72 else{
73 scanf("%d",&inc);
74 update(a,b,inc,1);
75 }
76 }
77 return 0;
78 }