#include <stdio.h>#include <algorithm>using namespace std;#define LL long long#define maxn 111111#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1LL add[maxn<<2];//add记录的是子节点一致增量,并不是累加和.LL sum[maxn<<2];void pushup(int rt){ sum[rt]=sum[rt<<1]+sum[rt<<1|1];}void pushdown(int rt,int m){ if(add[rt]) { add[rt<<1]+=add[rt]; add[rt<<1|1]+=add[rt]; sum[rt<<1]+=add[rt]*(m-(m>>1)); sum[rt<<1|1]+=add[rt]*(m>>1); add[rt]=0;//蛋疼啊!!先前的标记要进行消去,和成段更新的原理是一样的. }}void build(int l,int r,int rt){ add[rt]=0; if(l==r) { scanf("%lld",&sum[rt]); return ; } int mid=(r+l)>>1; build(lson); build(rson); pushup(rt);}void update(int a,int b,int c,int l,int r,int rt){ if(a<=l&&b>=r) { add[rt]+=c;//此处不是add[rt]=c,找了我将近两个小时。收不了了。 sum[rt]+=(LL)c*(r-l+1);//可能会2超范围 return ; } pushdown(rt,r-l+1); int mid=(r+l)>>1; if(a<=mid) update(a,b,c,lson); if(b>mid) update(a,b,c,rson); pushup(rt);}LL query(int a,int b,int l,int r,int rt)//LL{ if(a<=l&&b>=r) return sum[rt];//注意和单点查询的区别.当区间完全覆盖的时候输出节点的值即为区间和. pushdown(rt,r-l+1); int mid=(r+l)>>1; LL ret=0; if(a<=mid) ret+=query(a,b,lson); if(b>mid) ret+=query(a,b,rson); return ret;}int main(){ int n,m,a,b,c; scanf("%d%d",&n,&m); build(1,n,1); while(m--) { char op[2]; scanf("%s",op); if(op[0]=='C') { scanf("%d%d%d",&a,&b,&c); update(a,b,c,1,n,1); } else { scanf("%d%d",&a,&b); printf("%lld\n",query(a,b,1,n,1)); } } return 0;}