#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\n",Query(1,l,r));
}
else
{
scanf("%d%d%d",&l,&r,&e);
Update(1,l,r,e);
}
}
}
return 0;
}