与种花那题不同,此题区间内每一个数不止+1,而是+任意一个数。
只要将update操作中,增加一个参数即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
using namespace std;
const int maxn = 1e6+5;
long long n,m,t,l,r,value,a[maxn];
struct node{
long long l,r;
long long sum,lazy;
void update(long long x)
{
sum += (r-l+1)*x;
lazy += x;
}
}tree[maxn*4];
void push_up(long long x)
{
tree[x].sum = tree[x<<1].sum+tree[x<<1|1].sum;
}
void push_down(long long x)
{
long long lazyval = tree[x].lazy;
if(lazyval){
tree[x<<1].update(lazyval);
tree[x<<1|1].update(lazyval);
tree[x].lazy = 0;
}
}
void build(long long x,long long l,long long r)
{
tree[x].l = l,tree[x].r = r;
tree[x].sum = tree[x].lazy = 0;
if(l==r) {
tree[x].sum = a[l];
}
else{
long long mid = (l+r)/2;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
push_up(x);
}
}
void update(long long x,long long l,long long r,long long val)
{
long long L=tree[x].l,R=tree[x].r;
if(l<=L&&r>=R)
tree[x].update(val);
else{
push_down(x);
long long mid = (L+R)/2;
if(l<=mid)
update(x<<1,l,r,val);
if(r>mid)
update(x<<1|1,l,r,val);
push_up(x);
}
}
long long query(long long x,long long l,long long r)
{
long long L=tree[x].l,R=tree[x].r;
long long ans = 0;
if(l<=L&&r>=R)
ans += tree[x].sum;
else{
push_down(x);
// cout<<tree[2].sum<<" id"<<2<<endl;
// cout<<tree[5].sum<<" id"<<5<<endl;
// cout<<tree[4].sum<<" id"<<4<<endl;
long long mid = (L+R)/2;
if(l<=mid)
ans+=query(x<<1,l,r);
if(r>mid)
ans+=query(x<<1|1,l,r);
push_up(x);
//cout<<ans<<endl;
}
return ans;
}
int main()
{
freopen("d://test.txt","r",stdin);
scanf("%d%d" , &n,&m);
for(long long i=1;i<=n;i++)
scanf("%d" ,&a[i]);
build(1,1,n);
getchar();
for(int i=0;i<m;i++)
{
char s=getchar();
if(s=='Q') {
scanf("%d%d",&l, &r);
cout<<query(1,l,r)<<endl;
}
else{
scanf("%d%d%d", &l, &r, &value);
update(1,l,r,value);
}
getchar();
}
return 0;
}