社区讨论

k-d tree 求码风改良以及卡常

AT_abc437_f[ABC437F] Manhattan Christmas Tree 2参与者 29已保存回复 33

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
32 条
当前快照
1 份
快照标识符
@mjqwruq0
此快照首次捕获于
2025/12/29 16:40
2 个月前
此快照最后确认于
2026/01/01 18:10
2 个月前
查看原帖
rt,就是复习一下算法,没指望一定能过,当然能过最好。
本人是 k-d tree 新手,写的不太熟练,k-d tree 部分的码风可能不太好,求各位大佬看看有没有可以改进的地方。
另外这个代码超时了,各位大佬看一下哪里常数大了。当然卡不过去也没关系。
如果需要的话可以悬一个小号关注。
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=4e5+10;
const int inf=1e18+10,R=1e9+5;
struct ms{
	int x[3],l[3],r[3];
	bool e;
	int ls,rs,sz;
	int v[4],t[4];
	// a+b a-b -a+b -a-b
	void init(){
		sz=1;
		int a=x[1],b=x[2];
		v[0]=a+b;
		v[1]=a-b;
		v[2]=-a+b;
		v[3]=-a-b;
	}
}f[N<<2];
int cnt;
struct kd{
	int b[N],rt[N],cs;
	void push_up(int u){
		int ls=f[u].ls;
		int rs=f[u].rs;
		f[u].sz=f[ls].sz+f[rs].sz+(!f[u].e);
		for(int j=0;j<4;j++){
			if(!f[u].e) f[u].t[j]=f[u].v[j];
			else f[u].t[j]=-inf; 
		}
		for(int k=0;k<=2;k++){
			if(!f[u].e){
				f[u].l[k]=f[u].x[k];
				f[u].r[k]=f[u].x[k];
			}
			else{
				f[u].l[k]=inf;
				f[u].r[k]=-inf;
			}
		}
		auto rep=[&](int v){
			if(!f[v].sz) return;
			for(int j=0;j<4;j++){
				f[u].t[j]=max(f[u].t[j],f[v].t[j]);
			}
			for(int k=0;k<=2;k++){
				f[u].l[k]=min(f[u].l[k],f[v].l[k]);
				f[u].r[k]=max(f[u].r[k],f[v].r[k]);
			}
		};
		rep(ls);
		rep(rs);
	}
	int build(int l,int r,int dep){
		int m=(l+r)>>1;
		nth_element(b+l,b+m,b+r+1,[&](int c,int d){
			return f[c].x[dep]<f[d].x[dep];
		});
		int u=b[m];
		if(l<m) f[u].ls=build(l,m-1,(dep+1)%3);
		if(m<r) f[u].rs=build(m+1,r,(dep+1)%3);
		push_up(u);
		return u;
	}
	void append(int &u){
		if(!u) return;
		b[++cs]=u;
		append(f[u].ls);
		append(f[u].rs);
		u=0;
	}
	void ins(int u){
		cs=0;
		b[++cs]=u;
		for(int i=0;;i++){
			if(rt[i]){
				append(rt[i]);
			}
			else{
				rt[i]=build(1,cs,0);
				return;
			}
		}
	}
	bool c_in(int x,int y){// whether x is in y
		for(int k=0;k<=2;k++){
			if(!(f[y].l[k]<=f[x].l[k]&&f[x].r[k]<=f[y].r[k])) return 0;
		}
		return 1;
	}
	bool c_ex(int x,int y){// whether x is out of y
		for(int k=0;k<=2;k++){
			if(f[x].l[k]>f[y].r[k]||f[y].l[k]>f[x].r[k]) return 1;
		}
		return 0;
	}
	bool c_pos(int x,int y){// whether x can be contained in y
		for(int k=0;k<=2;k++){
			if(!(f[y].l[k]<=f[x].x[k]&&f[x].x[k]<=f[y].r[k])) return 0;
		}
		return 1;
	}
	int que(int u,int k,int pos){
		if(!u) return -inf;
		if(c_in(k,u)){
			return f[u].t[pos];
		}
		if(c_ex(k,u)){
			return -inf;
		}
		int res=-inf;
		if(!f[u].e&&c_pos(u,k)){
			res=max(res,f[u].v[pos]);
		}
		res=max({res,que(f[u].ls,k,pos),que(f[u].rs,k,pos)});
		return res;
	}
	int que_f(int k,int pos){
		int res=-inf;
		for(int i=0;i<=20;i++){
			res=max(res,que(rt[i],k,pos));
		}
		return res;
	}
	bool dfs(int u,int k){
		if(!u) return 0;
		if(!c_pos(k,u)) return 0;
		int ok=1;
		for(int j=0;j<=2;j++){
			if(f[u].x[j]!=f[k].x[j]){
				ok=0;
				break;
			}
		}
		if(ok){
			f[u].e=1;
			push_up(u);
			return 1;
		}
		int r=0;
		r|=dfs(f[u].ls,k);
		r|=dfs(f[u].rs,k);
		push_up(u);
		return r;
	}
	void del(int k){
		for(int i=0;i<=20;i++){
			if(dfs(rt[i],k)) return;
		}
	}
}t;
int n,q,a[N],b[N],g[N];
void nw(int i){
	g[i]=++cnt;
	f[cnt].x[0]=i;
	f[cnt].x[1]=a[i];
	f[cnt].x[2]=b[i];
	f[cnt].init();
}
void nq(int l0,int r0,int l1,int r1,int l2,int r2){
	++cnt;
	f[cnt].l[0]=l0;
	f[cnt].l[1]=l1;
	f[cnt].l[2]=l2;
	f[cnt].r[0]=r0;
	f[cnt].r[1]=r1;
	f[cnt].r[2]=r2;
}
signed main(){
//	freopen("std.in","r",stdin);
//	freopen("std.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n>>q;
	for(int i=1;i<=n;i++){
		cin>>a[i]>>b[i];
		nw(i);
		t.ins(cnt);
	}
	while(q--){
		int op,i,l,r,x,y;
		cin>>op;
		if(op==1){
			cin>>i>>x>>y;
			t.del(g[i]);
			a[i]=x;
			b[i]=y;
			nw(i);
			t.ins(cnt);
		}
		else{
			cin>>l>>r>>x>>y;
			nq(l,r,x,R,y,R);
			int w0=t.que_f(cnt,0);
			nq(l,r,x,R,-R,y);
			int w1=t.que_f(cnt,1);
			nq(l,r,-R,x,y,R);
			int w2=t.que_f(cnt,2);
			nq(l,r,-R,x,-R,y);
			int w3=t.que_f(cnt,3);
			int ans0=w0-x-y;
			int ans1=w1-x+y;
			int ans2=w2+x-y;
			int ans3=w3+x+y;
			int res=max({ans0,ans1,ans2,ans3});
			cout<<res<<"\n"; 
		}
	}
}

回复

33 条回复,欢迎继续交流。

正在加载回复...