题目链接

给n个点, 求出每个点到离它最近的点的距离。

直接建k-d树然后查询就可以  感觉十分神奇...

明白了算法原理但是感觉代码还不是很懂...

#include <bits/stdc++.h>
using namespace std;
#define pb(x) push_back(x)
#define ll long long
#define mk(x, y) make_pair(x, y)
#define lson l, m, rt<<1
#define mem(a) memset(a, 0, sizeof(a))
#define rson m+1, r, rt<<1|1
#define mem1(a) memset(a, -1, sizeof(a))
#define mem2(a) memset(a, 0x3f, sizeof(a))
#define rep(i, n, a) for(int i = a; i<n; i++)
#define fi first
#define se second
typedef complex <double> cmx;
typedef pair<int, int> pll;
const double PI = acos(-1.0);
const double eps = 1e-;
const int mod = 1e9+;
const int inf = ;
const int dir[][] = { {-, }, {, }, {, -}, {, } };
struct node
{
int p[];
int l, r, idx;
int operator [] (const int& idx)const
{
return p[idx];
}
}a[];
int cmpflag, idx[];
ll ans;
bool cmp(const node& x, const node& y)
{
return x[cmpflag] < y[cmpflag];
}
int build(int l, int r, int flag)
{
int mid = l + r >> ;
cmpflag = flag;
nth_element(a+l, a+mid, a+r+, cmp);
idx[a[mid].idx] = mid;
a[mid].l = (l != mid)?build(l, mid - , !flag):;
a[mid].r = (r != mid)?build(mid + , r, !flag):;
return mid;
}
ll dis(ll x, ll y = )
{
return x * x + y * y;
}
ll query(int rt, int flag, int x, int y)
{
ll tmp = dis(x - a[rt][], y - a[rt][]);
if(tmp) {
ans = min(ans, tmp);
}
if(a[rt].l && a[rt].r) {
bool d = !flag ? (x <= a[rt][]) : (y <= a[rt][]);
ll dist = !flag ? dis(x - a[rt][]) : dis(y - a[rt][]);
query(d?a[rt].l:a[rt].r, !flag, x, y);
if(dist < ans) {
query(!d?a[rt].l:a[rt].r, !flag, x, y);
}
} else if(a[rt].l) {
query(a[rt].l, !flag, x, y);
} else if(a[rt].r) {
query(a[rt].r, !flag, x, y);
}
}
int main()
{
int t, n;
cin>>t;
while(t--) {
cin>>n;
for(int i = ; i <= n; i++) {
scanf("%d%d", &a[i].p[], &a[i].p[]);
a[i].idx = i;
}
int root = build(, n, );
for(int i = ; i <= n; i++) {
ans = 1e18;
query(root, , a[idx[i]][], a[idx[i]][]);
printf("%lld\n", ans);
}
}
return ;
}
04-28 06:25