题目连接
k<<1 相当于 k*2
k<<1|1 相当于 k*2+1
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn=100000+10;
int a[maxn];
struct tree
{
int l,r;
LL sum;
LL Inc;
}f[maxn*4];
void bulid(int i,int l,int r)
{
f[i].l=l;
f[i].r=r;
f[i].Inc=0;
if(l==r)
{
f[i].sum=a[l];
return ;
}
int mid=(l+r)>>1;
bulid(i<<1, l, mid);
bulid(i<<1|1, mid+1, r);
f[i].sum=f[i<<1].sum+f[i<<1|1].sum;
}
void add(int i,int a,int b,LL c)
{
if(f[i].l==a&&f[i].r==b)
{
f[i].Inc+=c;
return ;
}
f[i].sum+=c*(b-a+1);
int mid=(f[i].l+f[i].r)>>1;
if(b<=mid)
add(i<<1, a, b, c);
else if(a>=mid+1)
add(i<<1|1, a, b, c);
else
{
add(i<<1, a,mid, c);
add(i<<1|1,mid+1,b,c);
}
}
LL query(int i,int a,int b)
{
if(f[i].l==a&&f[i].r==b)
{
return f[i].sum+f[i].Inc*(b-a+1);
}
f[i].sum+=(f[i].r-f[i].l+1)*f[i].Inc;
int mid=(f[i].l+f[i].r)>>1;
add(i<<1, f[i].l, mid, f[i].Inc);
add(i<<1|1,mid+1,f[i].r,f[i].Inc);
f[i].Inc=0;
if(b<=mid)
return query(i<<1, a, b);
else if(a>=mid+1) return query(i<<1|1, a, b);
else return query(i<<1, a, mid)+query(i<<1|1, mid+1,b);
}
int main ()
{
int n,m;
char s[5];
int l,r;
LL c;
while(~scanf("%d%d",&n,&m))
{
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
bulid(1, 1, n);
for(int i=1;i<=m;i++)
{
scanf("%s",s);
if(s[0]=='Q')
{
scanf("%d%d",&l,&r);
printf("%lld
",query(1, l, r));
}
else
{
scanf("%d%d%lld",&l,&r,&c);
add(1, l, r, c);
}
}
}
return 0;
}