求调
查看原帖
求调
1603819
little_zxh_qwq楼主2025/2/6 20:30
#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[114514];
int sgt[414514];
int lc[414514],rc[414514];
int tag[414514];
int build(int l,int r,int i){
	lc[i]=l;
	rc[i]=r;
	if(l==r){
		sgt[i]=a[l];
		return a[l];
	}
	int m=(l+r)>>1;
	sgt[i]=build(l,m,i<<1)+build(m+1,r,(i<<1)|1);
	return sgt[i];
}
void pushdown(int l,int r,int i,int x){
	if(l==lc[i]&&r==rc[i]){
		tag[i]+=(r-l+1)*x;
		sgt[i]+=tag[i];
		return;
	}
	int m=rc[i*2];
	if(l<=m){
		pushdown(l,m,i<<1,x);
	}
	if(r>=m+1){
		pushdown(m+1,r,(i<<1)|1,x);
	}
}
int query(int l,int r,int i){
	if(l==lc[i]&&r==rc[i]){
		return sgt[i];
	}
	int m=rc[i*2];
	if(tag[i]){
		sgt[i]+=tag[i];
		pushdown(lc[i<<1],rc[i<<1],i<<1,tag[i]/(rc[i]-lc[i]+1));
		pushdown(lc[(i<<1)|1],rc[(i<<1)|1],(i<<1)|1,tag[i]/(rc[i]-lc[i]+1));
		tag[i]=0;
	}
	int sum=0;
	if(l<=m){
		sum+=query(l,m,i<<1);
	}
	if(r>=m+1){
		sum+=query(m+1,r,(i<<1)|1);
	}
	return sum;
}
main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	int t=build(1,n,1);
	for(int i=1;i<=m;i++){
		int op,l,r;
		cin>>op>>l>>r;
		if(op==1){
			int x;
			cin>>x;
			pushdown(l,r,1,x);
		}
		else{
			cout<<query(l,r,1)<<endl;
		}
	}
	for(int i=1;i<=n*4;i++){
		cout<<i<<" "<<lc[i]<<" "<<rc[i]<<" "<<tag[i]<<" "<<sgt[i]<<endl;
	}
} 

我估计是犯了个唐诗的错误,但我没看出来

2025/2/6 20:30
661573
_LRH_2025/2/6 20:32

O.O为什么姐姐的写法这么独特(挠头

2025/2/6 20:32
1058410
Gcc_Gdb_7_8_12025/2/6 20:32

@little_zxh_qwq pushdown 不能这么乱写啊,要和 Update 分开

2025/2/6 20:32
1603819
little_zxh_qwq楼主2025/2/6 20:33

@Gcc_Gdb_7_8_1

这不差不多吗/yiw

2025/2/6 20:33
1058410
Gcc_Gdb_7_8_12025/2/6 20:33

什么逆天写法,把 update 和 pushdown 弄在一起,又在 query 调用 pushdown,好奇特

2025/2/6 20:33
1603819
little_zxh_qwq楼主2025/2/6 20:34

@Gcc_Gdb_7_8_1 理解不了,能说的更详细一点吗

2025/2/6 20:34
661573
_LRH_2025/2/6 20:34

@little_zxh_qwq

#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[114514];
int sgt[414514];
int lc[414514],rc[414514];
int tag[414514];
int build(int l,int r,int i){
	lc[i]=l;
	rc[i]=r;
	if(l==r){
		sgt[i]=a[l];
		return a[l];
	}
	int m=(l+r)>>1;
	sgt[i]=build(l,m,i<<1)+build(m+1,r,(i<<1)|1);
	return sgt[i];
}
void pushdown(int l,int r,int i,int x){
	if(l==lc[i]&&r==rc[i]){ //姐姐这里它不一定就是一整段区间刚好配上的,线段树是要把目标区间分成许多个小区间去操作的
		tag[i]+=(r-l+1)*x;
		sgt[i]+=tag[i];
		return;
	}
	int m=rc[i*2];
	if(l<=m){
		pushdown(l,m,i<<1,x);
	}
	if(r>=m+1){
		pushdown(m+1,r,(i<<1)|1,x);
	}
}
int query(int l,int r,int i){
	if(l==lc[i]&&r==rc[i]){
		return sgt[i];
	}
	int m=rc[i*2];
	if(tag[i]){
		sgt[i]+=tag[i];
		pushdown(lc[i<<1],rc[i<<1],i<<1,tag[i]/(rc[i]-lc[i]+1));
		pushdown(lc[(i<<1)|1],rc[(i<<1)|1],(i<<1)|1,tag[i]/(rc[i]-lc[i]+1));
		tag[i]=0;
	}
	int sum=0;
	if(l<=m){
		sum+=query(l,m,i<<1);
	}
	if(r>=m+1){
		sum+=query(m+1,r,(i<<1)|1);
	}
	return sum;
}
main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	int t=build(1,n,1);
	for(int i=1;i<=m;i++){
		int op,l,r;
		cin>>op>>l>>r;
		if(op==1){
			int x;
			cin>>x;
			pushdown(l,r,1,x);
		}
		else{
			cout<<query(l,r,1)<<endl;
		}
	}
	for(int i=1;i<=n*4;i++){
		cout<<i<<" "<<lc[i]<<" "<<rc[i]<<" "<<tag[i]<<" "<<sgt[i]<<endl;
	}
}
2025/2/6 20:34
1058410
Gcc_Gdb_7_8_12025/2/6 20:35

@little_zxh_qwq

差不多?

建议重学,pushdown 从来不要递归,他只是下放标记,且你在查询区间时修改区间(query 调用 pushdown(update))?

2025/2/6 20:35
1603819
little_zxh_qwq楼主2025/2/6 20:35

@Gcc_Gdb_7_8_1query的pushdown不会下传啊,在下一层就停下了

2025/2/6 20:35
180103
Ew_Cors2025/2/6 20:36

pushdown 递归调用,那我每次都在根节点打 tag 你不炸了吗

2025/2/6 20:36
1603819
little_zxh_qwq楼主2025/2/6 20:36

先别说我的写法,我函数名乱起的,能不能指出这个代码最根本的错误在哪里,谢谢

2025/2/6 20:36