#include<bits/stdc++.h>
#define int long long
using namespace std;
constexpr int MAXN=2e5+10;
constexpr int MAXTREE=8e5+10;
int n,f,op,l,r,k;
struct Tree{//支持区间加的线段树
int pl[MAXTREE],tree[MAXTREE],val[MAXN];
int sum[MAXTREE];
void Init(){
memset(pl,0,sizeof(pl));
memset(tree,0,sizeof(tree));
memset(val,0,sizeof(val));
memset(sum,0,sizeof(sum));
}
void Build(int l,int r,int i){
if(l==r){
sum[i]=val[l];
return;
}
int mid=(l+r)>>1;
Build(l,mid,i<<1);
Build(mid+1,r,i<<1|1);
sum[i]=sum[i<<1]+sum[i<<1|1];
return;
}
void Push(int i,int l,int r){
int mid=(l+r)>>1;
int L=i<<1,R=i<<1|1;
pl[L]+=pl[i],pl[R]+=pl[i];
sum[L]+=pl[i]*(mid-l+1);
sum[R]+=pl[i]*(r-mid);
pl[i]=0;
return;
}
void Add(int l,int r,int k,int nl,int nr,int i){//加的总范围 [l,r],单点要加的值 k,现在的区间 [nl,nr],线段树数组第 i 个
if(l<=nl && r>=nr){
pl[i]+=k;
sum[i]=(nr-nl+1)*k;
return;
}
Push(i,nl,nr);
int mid=(nl+nr)>>1;
if(mid>=l)Add(l,r,k,l,mid,i<<1);
if(mid<=r)Add(l,r,k,mid+1,r,i<<1|1);
sum[i]=sum[i<<1]+sum[i<<1|1];
return;
}
int Query(int ql,int qr,int nl,int nr,int i){//询问和总范围 [ql,qr],现在的区间 [nl,nr],线段树数组第 i 个,总和 S
int SS=0;
if(ql>=nl && nr<=qr)SS+=sum[i];
int mid=(nl+nr)>>1;
if(mid>=ql)SS+=Query(ql,qr,nl,mid,i<<1);
if(mid<=nr)SS+=Query(ql,qr,mid+1,nr,i<<1|1);
return SS;
}
}MyTree;
signed main(){
scanf("%lld%lld",&n,&f);
for(int i=1;i<=n;i++)scanf("%lld",&MyTree.val[i]);
MyTree.Build(1,n,1);
for(int i=0;i<f;i++){
scanf("%lld",&op);
if(op==1){
scanf("%lld%lld%lld",&l,&r,&k);
MyTree.Add(l,r,k,1,n,1);
}
else if(op==2){
scanf("%lld",&k);
MyTree.Add(1,1,k,1,n,1);
}
else if(op==3){
scanf("%lld",&k);
MyTree.Add(1,1,-k,1,n,1);
}
else if(op==4){
scanf("%lld%lld",&l,&r);
printf("%lld\n",MyTree.Query(l,r,1,n,1));
}
else{
printf("%lld\n",MyTree.Query(1,1,1,n,1));
}
}
return 0;
}
问题:RE