关于线段树QAQ
  • 板块学术版
  • 楼主You_Quiet
  • 当前回复15
  • 已保存回复15
  • 发布时间2023/3/24 15:51
  • 上次更新2023/10/23 20:42:32
查看原帖
关于线段树QAQ
421736
You_Quiet楼主2023/3/24 15:51

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

qq_emoji: bxqq_emoji: bxqq_emoji: bxqq_emoji: bxqq_emoji: bxqq_emoji: bxqq_emoji: bxqq_emoji: bx

#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

2023/3/24 15:51
加载中...