思路:线段树的区间add和区间查询模板
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
#define lson i*2,l,m
#define rson i*2+1,m+1,r
const int maxn = 100000+100;
LL sum[maxn*4];
LL addv[maxn*4];
void PushDown(int i,int num)
{
if (addv[i])
{
sum[i*2] +=addv[i]*(num-(num/2));
sum[i*2+1]+= addv[i]*(num/2);
addv[i*2] +=addv[i];
addv[i*2+1]+=addv[i];
addv[i]=0;
}
}
void PushUp(int i)
{
sum[i] = sum[i*2]+sum[i*2+1];
}
void build(int i,int l,int r)
{
addv[i]=0;
if (l==r)
{
scanf("%lld",&sum[i]);
return;
}
int m = (l+r)/2;
build(lson);
build(rson);
PushUp(i);
}
void update(int ql,int qr,int add,int i,int l,int r)
{
if (ql<=l && qr>=r)
{
addv[i]+=add;
sum[i]+=(LL)add*(r-l+1);
return;
}
PushDown(i,r-l+1);
int m = (l+r)/2;
if (ql <=m)
update(ql,qr,add,lson);
if (qr > m)
update(ql,qr,add,rson);
PushUp(i);
}
LL query(int ql,int qr,int i,int l,int r)
{
if (ql<=l && r<=qr)
{
return sum[i];
}
PushDown(i,r-l+1);
int m = (l+r)/2;
LL ans = 0;
if (ql <=m)
ans +=query(ql,qr,lson);
if (m<qr)
ans+=query(ql,qr,rson);
return ans;
}
int main()
{
int n,q;
while (scanf("%d%d",&n,&q)!=EOF && n&&q)
{
build(1,1,n);
while (q--)
{
char str[10];
scanf("%s",str);
int x,y,z;
if (str[0] =='Q')
{
scanf("%d%d",&x,&y);
printf("%lld\n",query(x,y,1,1,n));
}
else
{
scanf("%d%d%d",&x,&y,&z);
update(x,y,z,1,1,n);
}
}
}
}