#include<stdio.h>
const int MAX=100005;
int base[MAX];
struct Node
{
long long value;
long long delta;
};
Node tree[MAX*3];
long long build(int node,int l,int r)
{
tree[node].delta=0;
if(l==r) return tree[node].value=base[l];
int mid=(l+r)>>1;
tree[node].value=build(node<<1,l,mid)+build((node<<1)+1,mid+1,r);
return tree[node].value;
}
void update(int node,int l,int r,int lc,int rc,long long newDelta) //自上而下的更新
{
tree[node].value+=(rc-lc+1)*newDelta; //更新目标结点及其父结点的基值
if(l==lc&&r==rc)
{
tree[node].delta+=newDelta; //更新增量是为了提供其子结点使用,而不是为该结点自身使用
return;
}
int mid=(l+r)>>1;
if(mid<lc) update((node<<1)+1,mid+1,r,lc,rc,newDelta);
else if(mid>=rc) update(node<<1,l,mid,lc,rc,newDelta);
else
{
update(node<<1,l,mid,lc,mid,newDelta);
update((node<<1)+1,mid+1,r,mid+1,rc,newDelta);
}
}
void inquire(int node,int l,int r,int lc,int rc,long long &sum)
{
if(l==lc&&r==rc)
{
sum+=tree[node].value; //目标结点提供基值
return;
}
sum+=tree[node].delta*(rc-lc+1); //所有目标结点的父结点提供增量,目标结点的基值已发生更新
int mid=(l+r)>>1;
if(mid<lc) inquire((node<<1)+1,mid+1,r,lc,rc,sum);
else if(mid>=rc) inquire(node<<1,l,mid,lc,rc,sum);
else
{
inquire(node<<1,l,mid,lc,mid,sum);
inquire((node<<1)+1,mid+1,r,mid+1,rc,sum);
}
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&base[i]);
build(1,1,n);
int b1,b2;
char str[2];
for(int i=0;i<m;i++)
{
scanf("%s",str);
if(str[0]=='Q')
{
scanf("%d%d",&b1,&b2);
long long sum=0;
inquire(1,1,n,b1,b2,sum);
printf("%lld\n",sum); //和=基值+增量
}
else
{
long long delta;
scanf("%d%d%lld",&b1,&b2,&delta);
update(1,1,n,b1,b2,delta);
}
}
return 0;
}
|