题目大意:秋实大哥精心照料了很多花朵。现在所有的花朵排成了一行,每朵花有一个愉悦值。秋实大哥每天要对着某一段连续的花朵歌唱,然后这些花朵的愉悦值都会增加一个相同的值v(v可能为负)。同时他想知道每次他唱完歌后这一段连续的花朵的愉悦值总和是多少。
代码实现:
#include<cstdio>
#include<cstring>
using namespace std;
const int N=100005;
struct Node{
long long sum;
int add;
}tree[N<<2];
void push_up(int t){
tree[t].sum=tree[t<<1].sum+tree[t<<1|1].sum;
}
void push_down(int t,int L,int R){
if(!tree[t].add) return;
int mid=(L+R)>>1;
tree[t<<1].sum+=(long long)tree[t].add*(mid-L+1);
tree[t<<1|1].sum+=(long long)tree[t].add*(R-mid);
tree[t<<1].add+=tree[t].add;
tree[t<<1|1].add+=tree[t].add;
tree[t].add=0;
}
void build(int t,int L,int R){
if(L==R){
scanf("%lld",&tree[t].sum);
tree[t].add=0;
return;
}
int mid=(L+R)>>1;
build(t<<1,L,mid);
build(t<<1|1,mid+1,R);
push_up(t);
}
void update(int t,int L,int R,int l,int r,int c){
if(l<=L&&R<=r){
tree[t].sum+=(long long)c*(R-L+1);
tree[t].add+=c;
return;
}
push_down(t,L,R);
int mid=(L+R)>>1;
if(l<=mid) update(t<<1,L,mid,l,r,c);
if(r>mid) update(t<<1|1,mid+1,R,l,r,c);
push_up(t);
}
long long query(int t,int L,int R,int l,int r){
if(l<=L&&R<=r) return tree[t].sum;
push_down(t,L,R);
int mid=(L+R)>>1;
long long ans=0;
if(l<=mid) ans+=query(t<<1,L,mid,l,r);
if(r>mid) ans+=query(t<<1|1,mid+1,R,l,r);
return ans;
}
int main(){
int n,m,q,l,r,c;
while(~scanf("%d",&n)){
build(1,1,n);
scanf("%d",&m);
while(m--){
scanf("%d%d%d",&l,&r,&c);
update(1,1,n,l,r,c);
printf("%lld\n",query(1,1,n,l,r));
}
}
}