Crouy_Li_Dorac @ 2024-10-22 21:47:04
rt
#include<bits/stdc++.h>
#define lc p<<1
#define rc p<<1|1
//#define int long long
using namespace std;
const long long N=1e5+10;
long long n,m;
long long w[N];
struct node{
long long sum,l,r,add;
}tr[N*4];
void push(long long p){
tr[p].sum=tr[lc].sum+tr[rc].sum;
return;
}
void down(long long p){
if(tr[p].add){
tr[lc].sum+=tr[p].add*(tr[lc].r-tr[lc].l+1);
tr[lc].add+=tr[p].add;
tr[rc].sum+=tr[p].add*(tr[rc].r-tr[rc].l+1);
tr[rc].add+=tr[p].add;
tr[p].add=0;
}
return;
}
void bulid(long long p,long long l,long long r){
tr[p]={w[p],l,r,0};
if(l==r) return;
long long m=l+r>>1;
bulid(lc,l,m);
bulid(rc,m+1,r);
push(p);
return;
}
void update(long long p,long long x,long long y,long long k){
if(x<=tr[p].l&&y>=tr[p].r){
tr[p].add+=k;
tr[p].sum+=k*(tr[p].r-tr[p].l+1);
return;
}
down(p);
long long m=tr[p].l+tr[p].r>>1;
if(x<=m) update(lc,x,y,k);
if(y>m) update(rc,x,y,k);
push(p);
}
long long query(long long p,long long x,long long y){
if(tr[p].l>=x&&tr[p].r<=y) return tr[p].sum;
down(p);
long long res=0;
long long m=(tr[p].l+tr[p].r)>>1;
if(x<=m) res+=query(lc,x,y);
if(y>m) res+=query(rc,x,y);
return res;
}
int main(){
cin>>n>>m;
for(long long i=1;i<=n;i++) cin>>w[i];
bulid(1,1,n);
for(long long i=1;i<=m;i++){
long long op,x,y,k;
cin>>op;
if(op==1){
cin>>x>>y>>k;
update(1,x,y,k);
}
if(op==2){
cin>>x>>y;
long long ans=query(1,x,y);
cout<<ans<<endl;
}
}
return 0;
}
by Limitless_lmw @ 2024-10-22 21:55:10
@Crouy_Li_Dorac @Crouy_Li_Dorac
27行左右应改为
tr[p]={0,l,r,0};
if(l==r){
tr[p].sum=w[l];
return ;
}
by Limitless_lmw @ 2024-10-22 21:56:13
@Limitless_lmw 原因是你的 w 记录的是 1~n,而不是线段树的标号,另外 l==r 时才应该改动 tr[p].sum 然后在 push 的时候更新父节点
by Crouy_Li_Dorac @ 2024-10-22 22:01:28
@Limitless_lmw 过了,谢谢大佬,已关
by Crouy_Li_Dorac @ 2024-10-22 22:01:49
此贴结
by Limitless_lmw @ 2024-10-22 22:02:26
@Crouy_Li_Dorac 说句闲话:为什么今天这么多人写线段树 1 啊(还有线段树1的上上个帖子是我发的)