HDU 4347 KDTree

卧槽,自己徒手写了一发KDTree

只能说自己默写的

借鉴了一下别人的写法

然后D了半天BUG

最后发现define有问题

再也不用define了

#include<bits/stdc++.h>
#define SQ(x) (x)*(x)
using namespace std;
const int N=1e5+10;
int idx,k;
struct P{
	int x[5];
	bool operator <(const P &u)const{return x[idx]<u.x[idx];}
}A[N];
typedef pair<int,P> DIS;
priority_queue<DIS>Q;
vector<DIS> V;
struct KDTREE{
	int S[N<<2];P R[N<<2];
	void build(int p,int l,int r,int dep){
		if(l>r)return;
		S[p]=r-l;S[p*2]=S[p*2+1]=-1;
		idx=dep%k;int mid=(l+r)/2;
		nth_element(A+l,A+mid,A+r+1);
		R[p]=A[mid];
		build(p*2,l,mid-1,dep+1);
		build(p*2+1,mid+1,r,dep+1);
	}
	void query(int p,int m,int dep,P a){
		if(S[p]==-1)return;
		DIS tmp=DIS(0,R[p]);
		for(int i=0;i<k;++i)tmp.first+=SQ(tmp.second.x[i]-a.x[i]);
		int l=p*2,r=p*2+1,dim=dep%k,flag=0;
		if(a.x[dim]>=R[p].x[dim])swap(l,r);
		if(~S[l])query(l,m,dep+1,a);
		if(Q.size()<m)Q.push(tmp),flag=1;
		else{
			if(Q.top().first>tmp.first)Q.pop(),Q.push(tmp);
			if(SQ(R[p].x[dim]-a.x[dim])<Q.top().first)flag=1;
		}
		if(~S[r]&&flag)query(r,m,dep+1,a);
	}
}KDT;
int main(){
	ios::sync_with_stdio(0);cin.tie(0);
	int n,m;
	while(cin>>n>>k){
		for(int i=1;i<=n;++i)for(int j=0;j<k;++j)cin>>A[i].x[j];
		KDT.build(1,1,n,0);
		int T;
		cin>>T;
		while(T--){
			P a;
			for(int i=0;i<k;++i)cin>>a.x[i];
			cin>>m;
			KDT.query(1,m,0,a);
			V.clear();
			while(Q.size()){
				V.push_back(Q.top());
				Q.pop();
			}
			printf("the closest %d points are:\n",V.size());
			for(int i=V.size()-1;i>=0;--i){
				printf("%d",V[i].second.x[0]);
				for(int j=1;j<k;++j)printf(" %d",V[i].second.x[j]);
				printf("\n");
			}
		}
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值