Hf_Poem @ 2024-10-20 18:55:02
#include<bits/stdc++.h>
#define setp(a) fixed<<setprecision(a)
#define Venti cout<<endl<<"Venti!"<<endl
#define int long long
#define il inline
using namespace std;
const int V=1e6+10;
int n,m,a[V];
int len,tot,l[V],r[V],sum[V],bel[V],pre[V],add[V];
il void init(void){
len=sqrt(n),tot=(n-1)/len+1;
for(int i=1;i<=tot;i++)
l[i]=r[i-1]+1,r[i]=len*i;
r[tot]=n;
for(int i=1;i<=tot;i++){
for(int j=l[i];j<=r[i];j++)
bel[j]=i,sum[i]+=a[j];
pre[i]=pre[i-1]+sum[i];
}
}
il void modify(int lx,int rx,int x){
int p=bel[lx],q=bel[rx];
if(p==q){
for(int i=lx;i<=rx;i++)
a[i]+=x,sum[p]+=x;
for(int i=p;i<=tot;i++)
pre[i]=pre[i-1]+sum[i];
return;
}
for(int i=lx;i<=r[p];i++) a[i]+=x,sum[p]+=x;
for(int i=l[q];i<=rx;i++) a[i]+=x,sum[p]+=x;
for(int i=p+1;i<=q-1;i++)
add[i]+=x,sum[i]+=(r[i]-l[i]+1)*x;
for(int i=p;i<=tot;i++)
pre[i]=pre[i-1]+sum[i];
}
il int query(int lx,int rx){
int ans=0,p=bel[lx],q=bel[rx];
if(p==q){
for(int i=lx;i<=rx;i++)
ans+=a[i]+add[p];
return ans;
}
ans+=pre[q-1]-pre[p];
for(int i=lx;i<=r[p];i++) ans+=a[i]+add[p];
for(int i=l[q];i<=rx;i++) ans+=a[i]+add[q];
for(int i=p+1;i<=q-1;i++) ans+=sum[i];
return ans;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
init();
while(m--){
int op,x,y,val;
cin>>op;
if(op==1){
cin>>x>>y>>val;
modify(x,y,val);
}
else{
cin>>x>>y;
cout<<query(x,y)<<"\n";
}
}
cout<<endl;
return 0;
}
/*
*/
球挑啊
(我是怎么做到树状数组1和线段树1都挂的找不出问题贴板子求助的
by Clarinet @ 2024-10-20 18:57:04
@Hf_Poem 线段树板子题你用分块做?
by Hf_Poem @ 2024-10-20 18:58:15
@Czel_X 是可以的((((
by Hf_Poem @ 2024-10-20 18:58:25
@Czel_X 门口站着去
by cmpt_xiaoxiao @ 2024-10-20 19:05:40
@Czel_X 那咋了
by Clarinet @ 2024-10-20 19:12:59
@cmpt_xiaoxiao 没咋了
by h_rains @ 2024-10-20 19:14:04
@Hf_Poem 调出来了。
by Hf_Poem @ 2024-10-20 19:15:04
@h_rains !
by h_rains @ 2024-10-20 19:16:53
@Hf_Poem 首先你 query 的时候 ans+=pre[q-1]-pre[p]
这块求了一遍块和,后面你又用 for 循环求了一遍。然后你 update 的时候,在更新右边区间的时候,你 sum 下标写的 p
by Hf_Poem @ 2024-10-20 19:20:59
@h_rains 跌!!!!!!!!!