alex_liu @ 2023-03-07 14:07:48
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,lazy[100005],ans[100005<<2],a[100005<<2];
inline void build(int x,int y,int num){
if(x^y)build(x,x+y>>1,num<<1),build((x+y>>1)+1,y,num<<1|1),ans[num]=ans[num<<1]+ans[num<<1|1];
else ans[num]=a[x];
}
inline void update(int lx,int ly,int x,int y,int num,int k){
if(lx<=x&&ly>=y){
lazy[num]+=k,ans[num]+=(y-x+1)*k;
return;
}
int mid=x+y>>1;
lazy[num<<1]+=lazy[num],lazy[num<<1|1]+=lazy[num];
ans[num<<1]+=lazy[num]*(mid-x+1),ans[num<<1|1]+=lazy[num]*(y-mid);
lazy[num]=0;
if(lx<=mid)update(lx,ly,x,mid,num<<1,k);
if(ly>mid)update(lx,ly,mid+1,y,num<<1|1,k);
ans[num]=ans[num<<1]+ans[num<<1|1];
}
inline int query(int lx,int ly,int x,int y,int num){
if(lx<=x&&ly>=y)return ans[num];
int res=0,mid=x+y>>1;
lazy[num<<1]+=lazy[num],lazy[num<<1|1]+=lazy[num];
ans[num<<1]+=lazy[num]*(mid-x+1),ans[num<<1|1]+=lazy[num]*(y-mid);
lazy[num]=0;
if(lx<=mid)res+=query(lx,ly,x,mid,num<<1);
if(ly>mid)res+=query(lx,ly,mid+1,y,num<<1|1);
return res;
}
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
build(1,n,1);
for(int i=1,opt,x,y,k;i<=m;i++){
cin>>opt>>x>>y;
if(opt==1)cin>>k,update(x,y,1,n,1,k);
else cout<<query(x,y,1,n,1)<<endl;
}
return 0;
}
by y_kx_b @ 2023-03-07 14:16:43
btdjbl(doge
by y_kx_b @ 2023-03-07 14:20:31
@alex_liu 你 lazy 不开 4 倍空间?
其实 lazy 好像 2倍空间就够了,不过我不清楚,我一直写的是 2 倍空间的线段树(
by 快速herself变换 @ 2023-03-07 14:32:14
lazy数组开4倍空间 qwq
by Z1qqurat @ 2023-03-07 15:13:32
这♂个♂标♂题♂党♂好♂评♂
by zjx331 @ 2023-03-07 16:39:14
哲♂学♂标♂题♂好♂评
by alex_liu @ 2023-03-08 13:10:43
@y_kx_b /bx