这么个线段树版子还要解释
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long
using namespace std;
int n,m;
int f,x,y,k;
int tree[800001];
int lazy[800001];
void pushdown(int R,int l,int r){
if(lazy[R]){
lazy[R<<1]+=lazy[R];
lazy[R<<1|1]+=lazy[R];
int mid= (l+r)>>1;
tree[R<<1]+=lazy[R]*(mid-l+1);
tree[R<<1|1]+=lazy[R]*(r-mid);
lazy[R]=0;
}
}
void pushup(int r){
tree[r]=tree[r<<1]+tree[r<<1|1];
}
void add(int root,int L,int R,int l,int r,int v){
if(l<=L&&r>=R){
lazy[root]+=v;
tree[root]+=(R-L+1)*v;
return ;
}
pushdown(root,L,R);
int mid=(L+R)>>1;
if(l<=mid) add(root<<1,L,mid,l,r,v);
if(r>mid) add(root<<1|1,mid+1,R,l,r,v);
pushup(root);
}
int query(int root,int L,int R,int l,int r){
if(l<=L&&r>=R){
return tree[root];
}
int mid=(L+R)>>1,ans=0;
pushdown(root,L,R);
if(l<=mid) ans+=query(root<<1,L,mid,l,r);
if(r>mid) ans+=query(root<<1|1,mid+1,R,l,r);
return ans;
}
signed main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i){
scanf("%d",&x);
add(1,1,n,i,i,x);
}
for(int i=1;i<=m;++i){
scanf("%d",&f);
if(f==1){
scanf("%d%d%lld",&x,&y,&k);
add(1,1,n,x,y,k);
}
if(f==2){
scanf("%d",&x);
add(1,1,n,1,1,x);
}
if(f==3){
scanf("%d",&x);
add(1,1,n,1,1,-x);
}
if(f==4){
scanf("%d%d",&x,&y);
cout<<query(1,1,n,x,y)<<endl;
}
if(f==5){
cout<<query(1,1,n,1,1)<<endl;
}
}
return 0;
}