线段树,思路
#include<bits/stdc++.h>
#define int long long
#define double long double
#define INF INT_MAX
using namespace std;
const int maxn=2e5+5;
int n,m;
int a[maxn];
struct Tree{
int l,r,val,add;
#define l(x) t[x].l
#define r(x) t[x].r
#define sum(x) t[x].val
#define add(x) t[x].add
}t[maxn*4];
void build(int dq,int l,int r){
l(dq)=l,r(dq)=r;
if(l==r){
sum(dq)=a[l];
return;
}
int mid=(l+r)/2;
build(dq*2,l,mid);
build(dq*2+1,mid+1,r);
sum(dq)=sum(dq*2)+sum(dq*2+1);
}
void spread(int dq){
if(add(dq)){
sum(dq*2)+=add(dq)*(r(dq*2)-l(dq*2)+1);
sum(dq*2+1)+=add(dq)*(r(dq*2+1)-l(dq*2+1)+1);
add(dq*2)+=add(dq);
add(dq*2+1)+=add(dq);
add(dq)=0;
}
}
void change1(int dq,int x,int v){
if(l(dq)==r(dq)){
sum(dq)+=v;
return;
}
int mid=(l(dq)+r(dq))/2;
if(x<=mid) change1(dq*2,x,v);
else change1(dq*2+1,x,v);
sum(dq)=sum(dq*2)+sum(dq*2+1);
}
void change2(int dq,int l,int r,int d){
if(l<=l(dq) && r(dq)<=r){
sum(dq)+=d*(r(dq)-l(dq)+1);
add(dq)+=d;
return;
}
spread(dq);
int mid=(l(dq)+r(dq))/2;
if(l<=mid) change2(dq*2,l,r,d);
if(r>mid) change2(dq*2+1,l,r,d);
sum(dq)=sum(dq*2)+sum(dq*2+1);
}
int ask(int dq,int l,int r){
if(l<=l(dq) && r(dq)<=r) return sum(dq);
spread(dq);
int mid=(l(dq)+r(dq))/2;
int k=0;
if(l<=mid) k+=ask(dq*2,l,r);
if(r>mid) k+=ask(dq*2+1,l,r);
return k;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
build(1,1,n);
while(m--){
int op,x,y,k;
cin>>op;
if(op==1){
cin>>x>>y>>k;
change2(1,x,y,k);
}
if(op==2){
cin>>k;
change1(1,1,k);
}
if(op==3){
cin>>k;
change1(1,1,-k);
}
if(op==4){
cin>>x>>y;
cout<<ask(1,x,y)<<endl;
}
if(op==5) cout<<ask(1,1,1)<<endl;
}
return 0;
}