因为防止爆空间(然鹅这题不会爆)没写结构体,L,R指的是现在递归到的点的左右边界(闭区间),l,r是查询/修改的区间 另外因为实在找不出来问题,所以#define int long long 了,所以请忽略我乱七八糟的变量类型。code:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int M=1e5+10;
typedef long long ll;
int n,m;
ll a[M],sgt[M*4],lzt[M*4];
void up(int p){
sgt[p]=sgt[p*2]+sgt[p*2+1];
}
void build(int p,int L,int R){
if(L==R){
sgt[p]=a[L];
return;
}
int mid=(L+R)/2;
build(p*2,L,mid),build(p*2+1,mid+1,R);
up(p);
}
void mtag(int u,int len,ll v){
lzt[u]+=v;
sgt[u]+=len*v;
}
void down(int u,int L,int R){
int mid=(L+R)/2;
mtag(u*2,mid-L+1,lzt[u]);
mtag(u*2+1,R-mid,lzt[u]);
}
ll query(int p,int l,int r,int L,int R){
if(l<=L&&R<=r) return sgt[p];
else if(!(R<l||r<L)){
down(p,L,R);
int mid=(L+R)/2;
return query(p*2,l,r,L,mid)+query(p*2+1,l,r,mid+1,R);
}
else return 0;
}
void update(int p,int l,int r,int L,int R,ll av){
if(l<=L&&R<=r) mtag(p,R-L+1,av);
else if(!(R<l||r<L)){
down(p,L,R);
int mid=(L+R)/2;
update(p*2,l,r,L,mid,av);
update(p*2+1,l,r,mid+1,R,av);
up(p);
}
}
signed main(){
cin>>n>>m;
for(int i=1;i<=n;++i) cin>>a[i];
build(1,1,n);
for(int i=1,t,x,y;i<=m;++i){
cin>>t;ll k;
if(t==1){
cin>>x>>y>>k;
update(1,x,y,1,n,k);
}
else{
cin>>x>>y;
cout<<query(1,x,y,1,n)<<"\n";
}
}
return 0;
}