hdu 2966 In case of failure k-d树
给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-8; const int mod = 1e9+7; const int inf = 1061109567; const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; struct node { int p[2]; int l, r, idx; int operator [] (const int& idx)const { return p[idx]; } }a[100005]; int cmpflag, idx[100005]; 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 >> 1; cmpflag = flag; nth_element(a+l, a+mid, a+r+1, cmp); idx[a[mid].idx] = mid; a[mid].l = (l != mid)?build(l, mid - 1, !flag):0; a[mid].r = (r != mid)?build(mid + 1, r, !flag):0; return mid; } ll dis(ll x, ll y = 0) { return x * x + y * y; } ll query(int rt, int flag, int x, int y) { ll tmp = dis(x - a[rt][0], y - a[rt][1]); if(tmp) { ans = min(ans, tmp); } if(a[rt].l && a[rt].r) { bool d = !flag ? (x <= a[rt][0]) : (y <= a[rt][1]); ll dist = !flag ? dis(x - a[rt][0]) : dis(y - a[rt][1]); 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 = 1; i <= n; i++) { scanf("%d%d", &a[i].p[0], &a[i].p[1]); a[i].idx = i; } int root = build(1, n, 0); for(int i = 1; i <= n; i++) { ans = 1e18; query(root, 0, a[idx[i]][0], a[idx[i]][1]); printf("%lld\n", ans); } } return 0; }