本人已经重复四次挑战线段树1板子,每次打都会先错,然后慢慢捣鼓出来,又陷入了疑惑,想知道这样的push_down为什么是错误的,请大佬指正!万分感谢








#include<iostream>
using namespace std;
const int N=1e5+10;
int n,m;
long long sum[N*8],lazy[N*8],a[N];
void push_up(int idx,int l,int r){
sum[idx]=sum[idx*2]+sum[idx*2+1];
}
void build(int idx,int l,int r){
if(l==r){
sum[idx]=a[l];
return;
}
int mid=(l+r)>>1;
build(idx*2,l,mid);
build(idx*2+1,mid+1,r);
push_up(idx,l,r);
}
void push_down(int idx,int l,int r){
sum[idx]+=(r-l+1)*lazy[idx];
lazy[idx*2]+=lazy[idx];
lazy[idx*2+1]+=lazy[idx];
lazy[idx]=0;
}
void change(int idx,int l,int r,int dl,int dr,int k){
push_down(idx,l,r);
if(l==dl&&r==dr){
lazy[idx]+=k;
push_down(idx,l,r);
return;
}
int mid=(l+r)>>1;
if(dr<=mid) change(idx*2,l,mid,dl,dr,k);
else if(dl>mid) change(idx*2+1,mid+1,r,dl,dr,k);
else{
change(idx*2,l,mid,dl,mid,k);
change(idx*2+1,mid+1,r,mid+1,dr,k);
}
push_up(idx,l,r);
}
long long check(int idx,int l,int r,int dl,int dr){
push_down(idx,l,r);
if(l==dl&&r==dr) return sum[idx];
int mid=(l+r)>>1;
long long ans=0;
if(dr<=mid) ans+=check(idx*2,l,mid,dl,dr);
else if(dl>mid) ans+=check(idx*2+1,mid+1,r,dl,dr);
else{
ans+=check(idx*2,l,mid,dl,mid);
ans+=check(idx*2+1,mid+1,r,mid+1,dr);
}
push_up(idx,l,r);
return ans;
}
int main()
{
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>>x>>y;
if(op==1){
cin>>k;
change(1,1,n,x,y,k);
}
else cout<<check(1,1,n,x,y)<<endl;
}
}
下了一个测试点:
输入:
8 10
640 591 141 307 942 58 775 133
2 1 5
2 3 8
2 3 6
2 5 8
2 4 8
1 4 8 60
2 1 6
2 5 8
1 3 7 15
1 2 6 86
输出:
2621
2356
1448
1908
2215
2859
2148
样例已过QAQ