// 对于延迟更新,我们在updata 和query的时候 pushdown和pushup两个东西都要存在
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
typedef long long ll;
struct node
{
ll l,r,sum,add;
} tree[10000*4];
ll a[100001];
//ll x,y;
void pushup(int id)
{
tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;
}
void build(ll l,ll r,int id)
{
if(l==r)
{
tree[id].sum=a[l];
return;
}
tree[id].l=l;
tree[id].r=r;
tree[id].add=0;
ll mid=(l+r)/2;
build(l,mid,id*2);
build(mid+1,r,id*2+1);
pushup(id);
}
void pushdown(int id)
{
if(tree[id].add)
{
tree[id*2].add +=tree[id].add;
tree[id*2+1].add += tree[id].add;
tree[id*2].sum += (tree[id*2].r-tree[id*2].l+1)*(tree[id*2].add);
tree[id*2+1].sum += (tree[id*2+1].r-tree[id*2+1].l+1)*(tree[id*2+1].add);
tree[id].add=0;
}
}
void updata(ll x,ll y,ll l,ll r,int id,ll k)
{
if(x<=l && r<=y)// 在区间里面 就可以做一定操作
{
tree[id].sum += (r-l+1)*k;
tree[id].add += k;
return;
}
pushdown(id);//
ll mid=(l+r)/2;
if(x <= mid) updata(x,y,l,mid,id*2,k);
if(y > mid) updata(x,y,mid+1,r,id*2+1,k);
pushup(id);
}
ll query(ll x,ll y,ll l,ll r,int id)
{
if(x<=l && r<=y)
{
return tree[id].sum;
}
pushdown(id);
ll mid=(l+r)/2;
ll sum=0;
if(x<=mid) sum+=query(x,y,l,mid,id*2);
if(y>mid) sum+=query(x,y,mid+1,r,id*2+1);
pushup(id);//
return sum;
}
int main()
{
int n,q;
ll x,y,k;
while(scanf("%d %d",&n,&q)!=EOF)
{
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
}
build(1,n,1);
while(q--)
{
char s[3];
scanf("%s",s);
if(s[0]=='Q')
{
scanf("%lld %lld",&x,&y);
printf("%lld\n",query(x,y,1,n,1));
}
else if(s[0]=='C')
{
scanf("%lld %lld %lld",&x,&y,&k);
updata(x,y,1,n,1,k);
}
}
}
return 0;
}