如果不下推会出现错误,尤其是区间修改的时候
点修改可以不用下推;
上推也不要漏掉,修改查询建树都要上推;
还有就是注意longlong类型 一个没改就不行,我当时Query返回类型忘了改一直wa,改了就过了。
#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;
long long sum[500000],Add[500000]={0};
void Pushdown(int rt,int m){
if(Add[rt]){
Add[rt*2]+=Add[rt];
Add[rt*2+1]+=Add[rt];
sum[rt*2]+=(m-m/2)*Add[rt];
sum[rt*2+1]+=(m/2)*Add[rt];
Add[rt]=0;
}
}
void Pushup(int rt){
sum[rt]=sum[rt*2]+sum[rt*2+1];
}
void build(int l,int r,int rt){
if(l==r) {
scanf("%lld",&sum[rt]);return ;
}
long long m=(l+r)/2;
build(l,m,rt*2);
build(m+1,r,rt*2+1);
Pushup(rt);
}
void update(int L,int R,long long j,int l,int r,int rt){
if(L<=l&&R>=r) {
sum[rt]+=j*(r-l+1);
Add[rt]+=j;
return ;
}
Pushdown(rt,r-l+1);
long long m=(l+r)/2;
if(L<=m) update(L,R,j,l,m,rt*2);
if(R>m) update(L,R,j,m+1,r,rt*2+1);
Pushup(rt);
}
long long Query(int L,int R,int l,int r,int rt){
if(L<=l&&R>=r){
return sum[rt];
}
long long m=(r+l)/2;
Pushdown(rt,r-l+1);
long long Ans=0;
if(L<=m) Ans+=Query(L,R,l,m,rt*2);
if(R>m) Ans+=Query(L,R,m+1,r,rt*2+1);
Pushup(rt);//注意这里也要上推;
return Ans;
}
int main()
{
int N,Q;
scanf("%d%d",&N,&Q);
build(1,N,1);
while(Q--){
char s[10];
scanf("%s",s);
if(s[0]=='C'){
long long a,b,c;
scanf("%lld%lld%lld",&a,&b,&c);
update(a,b,c,1,N,1);
}
if(s[0]=='Q'){
long long i,j;
scanf("%lld%lld",&i,&j);
long long ans=Query(i,j,1,N,1);
printf("%lld\n",ans);
}
}
return 0;
}