题意:
给定n个旅馆,m个人,每个旅馆有一个价格,每个人有个能承受的最大的价格
对于每个人,输出离他最近的,并且价格在其承受范围之内的旅馆的坐标和价格
思路:
这个题一看就是最近点对,但是也没想那么多,直接套上kd-tree板子改了一下就过了
其实这个题要是所有的旅馆在一个大圆上,所有的人都在圆心附近,这样的话复杂度就很高了,可能是随机的数据比较弱
再说kd-tree: 刚刚现学的,现手推了一下板子,就是按坐标的维度建一棵二叉树,查找的时候按照远近的规则往下查找,复杂度logn;
处理这个题的时候,n个旅馆直接建树,对于m个人来说,每次查询的时候,先插入进去,删点标记flg设为1;直接查找,在更新最优解(最短距离)时,加上一个条件,就是旅馆价格在这个人承受范围内的话才进行判定更新,然后依次查询;
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 3e5;
const ll INF = 0x3f3f3f3f3f3f3f3f;
struct kdnode {
ll l,r,x[2], v;
bool flg;
} kdt[N],pt;
int cnt,D,rt;
int n,m;
void init() {
D = 2;
cnt = 0;
rt = -1;
}
int add(kdnode pt) {
kdt[cnt].flg = 0;
kdt[cnt].l = kdt[cnt].r = -1;
kdt[cnt].v = pt.v;
for(int i = 0; i < D; i++)
kdt[cnt].x[i] = pt.x[i];
return cnt++;
}
void insert_(int rt,kdnode pt,int d) {
d %= D;
if(pt.x[d]<kdt[rt].x[d]) {
if(kdt[rt].l==-1)
kdt[rt].l = add(pt);
else
insert_(kdt[rt].l,pt,d+1);
} else {
if(kdt[rt].r==-1)
kdt[rt].r = add(pt);
else
insert_(kdt[rt].r,pt,d+1);
}
}
ll dist(kdnode a,kdnode b) {
ll ret = 0;
for(int i = 0; i < D; i++)
ret += (a.x[i]-b.x[i])*(a.x[i]-b.x[i]);
return ret;
}
int idx;
ll ds;
void query(int rt,kdnode pt,int d) {
d %= D;
if(rt==-1)
return;
if(!kdt[rt].flg && kdt[rt].v <= pt.v) {
ll dss = dist(kdt[rt],pt);
if(ds>dss)
idx=rt,ds=dss;
}
if(pt.x[d]<=kdt[rt].x[d]) {
query(kdt[rt].l,pt,d+1);
ll dd = (kdt[rt].x[d]-pt.x[d])*(kdt[rt].x[d]-pt.x[d]);
if(dd<ds)
query(kdt[rt].r,pt,d+1);
}
if(pt.x[d]>=kdt[rt].x[d]) {
query(kdt[rt].r,pt,d+1);
ll dd = (kdt[rt].x[d]-pt.x[d])*(kdt[rt].x[d]-pt.x[d]);
if(dd<ds)
query(kdt[rt].l,pt,d+1);
}
}
int main() {
int T;
scanf("%d", &T);
while(T--) {
init();
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i) {
scanf("%lld%lld", &pt.x[0], &pt.x[1]);
scanf("%lld", &pt.v);
if(rt == -1) {
rt = add(pt);
} else {
insert_(rt, pt, 0);
}
}
for(int i = 1; i <= m; ++i) {
idx = rt;
ds = INF;
scanf("%lld%lld", &pt.x[0], &pt.x[1]);
scanf("%lld", &pt.v);
if(rt == -1) {
rt = add(pt);
} else {
insert_(rt, pt, 0);
}
kdt[n+i-1].flg = 1;
query(rt, kdt[n+i-1], 0);
printf("%lld %lld %lld\n", kdt[idx].x[0], kdt[idx].x[1], kdt[idx].v);
}
}
return 0;
}