萌新刚学线段树,照着这篇博客打了半小时,样例都没过……QAQ
#include<iostream>
using namespace std;
int n,m,ans[500000],a[500000],tag[500001];
inline int ls(int p){
return p<<1;
}
inline int rs(int p){
return p<<1|1;
}
void push_up_sum(int p){
ans[p]=ans[ls(p)]+ans[rs(p)];
}
void push_up_min(int p){
ans[p]=min(ans[ls(p)],ans[rs(p)]);
}
void push_up_max(int p){
ans[p]=max(ans[ls(p)],ans[rs(p)]);
}
void build(int p,int l,int r){
tag[p]=0;
if(l==r){
ans[p]=a[l];
return;
}
int mid=(l+r)>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
push_up_sum(p);//可以根据实际需要修改
}
inline void f(int p,int l,int r,int k){
tag[p]=tag[p]+k;
ans[p]=ans[p]+k*(r-l+1);
}
inline void push_down(int p,int l,int r){
int mid=(l+r)>>1;
f(ls(p),l,mid,tag[p]);
f(rs(p),mid+1,r,tag[p]);
tag[p]=0;
}
inline void update(int nl,int nr,int l,int r,int p,int k){
if(nl<=l&&r<=nr){
ans[p]+=k*(r-l+1);
tag[p]+=k;
return;
}
push_down(p,l,r);
int mid=(l+r)>>1;
if(nl<=mid)update(nl,nr,l,mid,ls(p),k);
if(nr>mid)update(nl,nr,mid+1,r,rs(p),k);
push_up_sum(p);
}
int query(int qx,int qy,int l,int r,int p){
int sum=0;
if(qx<=l&&r<=qy)return ans[p];
int mid=(l+r)>>1;
push_down(p,l,r);
if(qx<=mid)sum+=query(qx,qy,l,mid,ls(p));
if(qy>mid)sum+=query(qx,qy,mid+1,r,rs(p));
return sum;
}
int main(){
cin>>n>>m;
build(1,1,n);
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=m;i++){
int op,x,y;
cin>>op>>x>>y;
if(op==1){
int k;
cin>>k;
update(x,y,1,n,1,k);
}else{
cout<<query(x,y,1,n,1)<<endl;
}
}
return 0;
}