#include <iostream> #include <cstdio> using namespace std; #define maxn 100005 #define lson rt<<1 #define rson rt<<1|1 struct SegmentTree//建立一个结构体存储左右端点与区间内的值 { int l,r; long long sum,e; int Mid() { return (l+r)>>1; } int len() { return r-l+1; } } a[maxn<<2]; void BuildSegTree(int rt,int l,int r) { a[rt].l=l; a[rt].r=r; a[rt].e=0; if(l==r) { scanf("%lld",&a[rt].sum); return ; } BuildSegTree(lson,l,a[rt].Mid()); BuildSegTree(rson,a[rt].Mid()+1,r); a[rt].sum=a[lson].sum+a[rson].sum; } void PushDown(int rt) { a[lson].sum+=a[rt].e*a[lson].len(); a[lson].e+=a[rt].e; a[rson].sum+=a[rt].e*a[rson].len(); a[rson].e+=a[rt].e; a[rt].e=0; } void Update(int rt,int l,int r,int e) { a[rt].sum+=(r-l+1)*e; if(a[rt].l==l&&a[rt].r==r) { a[rt].e+=e; return ; } PushDown(rt); if(r<=a[rt].Mid()) Update(lson,l,r,e); else if(l>a[rt].Mid()) Update(rson,l,r,e); else { Update(lson,l,a[rt].Mid(),e); Update(rson,a[rt].Mid()+1,r,e); } } long long Query(int rt,int l,int r) { if(a[rt].l==l&&a[rt].r==r) { return a[rt].sum; } PushDown(rt); if(r<=a[rt].Mid()) return Query(lson,l,r); else if(l>a[rt].Mid()) return Query(rson,l,r); else { long long lsum=Query(lson,l,a[rt].Mid()); long long rsum=Query(rson,a[rt].Mid()+1,r); return lsum+rsum; } } int main() { int n,q; while(~scanf("%d%d",&n,&q)) { BuildSegTree(1,1,n); while(q--) { char s[10]; int l,r,e; scanf("%s",s); if(s[0]=='Q') { scanf("%d%d",&l,&r); printf("%lld ",Query(1,l,r)); } else { scanf("%d%d%d",&l,&r,&e); Update(1,l,r,e); } } } return 0; }