#include<iostream>
#include<algorithm>
#include<stdio.h>
using namespace std;
#define Lson rt<<1
#define Rson rt<<1|1
//这里写的和学长不一样,我遵从是叶子结点的四倍定义数组,学长定义的是 1e5+5<<1,
const int Maxn=1e5+5;
struct node
{
int mid, len, L, R;
__int64 e, sum;
} a[Maxn<<2];//第一次提交runtime了,我发现是数组开小了,我发现我定义的是叶子结点的二倍,粗心了。
//不过还是基础知识不牢固,毕竟我只是记住了结论,但不知从何而推来。
__int64 x;
void Buildsegtree(int rt, int L, int R);//建立
void pushdown(int rt);//下推
__int64 Query(int rt, int L, int R);//查询
void Update(int rt, int L, int R, int e);//更新
int main()
{
int n, m, a, b, c;
scanf("%d%d", &n, &m);
Buildsegtree(1, 1, n);
while(m--)
{
char s[3];
scanf("%s", s);
if(s[0]=='Q')
{
scanf("%d%d", &a, &b);
printf("%I64d\n", Query(1, a, b));
}
else
{
scanf("%d%d%d", &a, &b, &c);
Update(1, a, b, c);
}
}
return 0;
}
void Buildsegtree(int rt, int L, int R)//建立
{
a[rt].L=L;
a[rt].R=R;
a[rt].e=0;//这点没写,之后核对的时候才发现
a[rt].mid=(L+R)>>1;
a[rt].len=(R-L)+1;//我吧if语句写在了这些赋值语句之前,不知道可以不,
//反正改了过来,不过我觉得写前面后面都一样,毕竟它的叶子节点没有左孩子和有孩子了
//之后把他俩换了换位置发现不行
if(L==R)
{
scanf("%I64d", &x);
a[rt].sum=x;
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;
}
__int64 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)
Query(Lson, L, R);
else if(L>a[rt].mid)
Query(Rson, L, R);
else
{
__int64 Lsum=Query(Lson, L, a[rt].mid);
__int64 Rsum=Query(Rson, a[rt].mid+1, R);
return Lsum+Rsum;
}
}
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);
}
}