题目链接:https://vjudge.net/contest/332630#problem/K
/*
HDU - 5992 KD树求最近点
t组数据,n个酒店,m个客人
后接n行,给出酒店坐标x,y,酒店价格w
m行,给出客人坐标x,y。客人最大能接受价格w
求客人最大能接受价格内的最近酒店是哪个,距离相同时输出,选择顺序靠前的酒店
输出m行,第i个客人选择的酒店坐标,价格
1
3 3
1 1 1
3 2 3
2 3 2
2 2 1
2 2 2
2 2 3
ans:
1 1 1
2 3 2
3 2 3
把酒店价格当成第三个维度,建立三维KD树,搜索满足条件下的最近点
*/
#include<bits/stdc++.h>
#define M 200010
#define ll long long
using namespace std;
ll t,n,m,wb,x,y,z,rt,dis,ans;
ll sta[M],tot;
const ll inf=1e18;
struct point
{
ll c[3],w,id;
bool operator < (const point a) const
{
return this->c[wb]<a.c[wb];
}
} P[M];
struct node
{
ll mi[3],mx[3],ls,rs;
point tp;
} T[M];
void up(ll r)
{
ll ls=T[r].ls,rs=T[r].rs;
for(ll i=0; i<3; i++)
{
T[r].mi[i]=T[r].mx[i]=T[r].tp.c[i];
if(ls)
{
T[r].mi[i]=min(T[r].mi[i],T[ls].mi[i]);
T[r].mx[i]=max(T[r].mx[i],T[ls].mx[i]);
}
if(rs)
{
T[r].mi[i]=min(T[r].mi[i],T[rs].mi[i]);
T[r].mx[i]=max(T[r].mx[i],T[rs].mx[i]);
}
}
}
ll build(ll l,ll r,ll k)//暴力建树
{
if(l>r) return 0;
ll mid=(l+r)>>1,now=++tot;
wb=k,nth_element(P+l,P+mid,P+r+1),T[now].tp=P[mid];
T[now].ls=build(l,mid-1,(k+1)%3),T[now].rs=build(mid+1,r,(k+1)%3);
up(now);
return now;
}
ll getdis(ll rt)//返回点集中可能的最近点距离
{
ll res=0;
if(z<T[rt].mi[2]) return inf+1;
if(x>T[rt].mx[0]) res+=(x-T[rt].mx[0])*(x-T[rt].mx[0]);
if(x<T[rt].mi[0]) res+=(T[rt].mi[0]-x)*(T[rt].mi[0]-x);
if(y>T[rt].mx[1]) res+=(y-T[rt].mx[1])*(y-T[rt].mx[1]);
if(y<T[rt].mi[1]) res+=(T[rt].mi[1]-y)*(T[rt].mi[1]-y);
return res;
}
void query(ll rt)
{
ll dm=0,dl=inf+1,dr=inf+1,ls=T[rt].ls,rs=T[rt].rs;
if(T[rt].tp.c[2]>z) dm=inf;
if(dm==0)
{
dm = (T[rt].tp.c[0]-x)*(T[rt].tp.c[0]-x)+(T[rt].tp.c[1]-y)*(T[rt].tp.c[1]-y);
if(dm<dis)
{
dis=dm;
ans=rt;
}
else if(dm==dis)
{
ans = T[ans].tp.id < T[rt].tp.id ? ans:rt;
}
}
if(ls) dl=getdis(ls);
if(rs) dr=getdis(rs);
if(dl<dr)
{
if(dl<=dis) query(ls);
if(dr<=dis) query(rs);
}
else
{
if(dr<=dis) query(rs);
if(dl<=dis) query(ls);
}
}
int main()
{
for(scanf("%lld",&t); t; t--)
{
tot=0;
scanf("%lld%lld",&n,&m);
for(ll i=1; i<=n; i++)
{
for(ll j=0; j<3; j++) scanf("%lld",&P[i].c[j]);
P[i].id=i;
}
rt=build(1,n,0);
for(ll i=1; i<=m; i++)
{
scanf("%lld%lld%lld",&x,&y,&z);
dis=inf;
query(rt);
printf("%lld %lld %lld\n",T[ans].tp.c[0],T[ans].tp.c[1],T[ans].tp.c[2]);
}
}
}