#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<numeric>
#include<cmath>
#include<bitset>
using namespace std;
typedef long long LL;
typedef pair<int, LL> PII;
typedef pair<int, int> pii;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn = 211222;
const int maxD = 2;
const int maxM = 12;
const int mask = (1 << 30) - 1;
const LL INF = 4611686018427387903LL;
int now;
struct TPoint {
int x[maxD];
void read() {
for (int i = 0; i < 2; ++i)
scanf("%d", x + i);
}
void print(int n) {
for (int i = 0; i < n; ++i)
printf("%d ", x[i]);
puts("");
}
} p[maxn];
bool cmp(const TPoint& a, const TPoint& b) {
return a.x[now] < b.x[now];
}
template<typename T>
T sqr(T n) {
return n * n;
}
struct KDtree {
int K, n, top;
int split[maxn];
LL dis2[maxM];
TPoint stk[maxn];
TPoint kp[maxn];
TPoint mp;
void build(int l, int r) {
if (l >= r)
return;
int i, j, mid = (l + r) >> 1;
LL dif[maxD], mx;
for (i = 0; i < K; ++i) {
mx = dif[i] = 0;
for (j = l; j < r; ++j)
mx += kp[j].x[i];
mx /= r - l;
for (j = l; j < r; ++j)
dif[i] += sqr(kp[j].x[i] - mx);
}
now = 0;
for (i = 1; i < K; ++i)
if (dif[now] < dif[i])
now = i;
split[mid] = now;
nth_element(kp + l, kp + mid, kp + r, cmp);
build(l, mid);
build(mid + 1, r);
}
void update(const TPoint& p, int M) {
int i, j;
LL tmp = dist(p, mp);
for (i = 0; i < M; ++i)
if (dis2[i] > tmp) {
for (j = M - 1; j > i; --j) {
stk[j] = stk[j - 1];
dis2[j] = dis2[j - 1];
}
stk[i] = p;
dis2[i] = tmp;
break;
}
}
void nearest_search(int l, int r, int M) {
if (l >= r)
return;
int mid = (l + r) >> 1;
update(kp[mid], M);
if (l + 1 == r)
return;
LL d = mp.x[split[mid]] - kp[mid].x[split[mid]];
if (d <= 0) {
nearest_search(l, mid, M);
if (sqr(d) < dis2[M - 1])
nearest_search(mid + 1, r, M);
} else {
nearest_search(mid + 1, r, M);
if (sqr(d) < dis2[M - 1])
nearest_search(l, mid, M);
}
}
void range_search(int l, int r, int D) {
if (l >= r)
return;
int mid = (l + r) >> 1;
if (dist(kp[mid], mp) <= D * D) {
stk[top++] = kp[mid];
}
if (l + 1 == r)
return;
LL d = mp.x[split[mid]] - kp[mid].x[split[mid]];
if (d <= 0) {
range_search(l, mid, D);
if (sqr(d) <= sqr(D))
range_search(mid + 1, r, D);
} else {
range_search(mid + 1, r, D);
if (sqr(d) <= sqr(D))
range_search(l, mid, D);
}
}
void find_nearest(TPoint p, int M) {
for (int i = 0; i < M; ++i) {
dis2[i] = INF;
}
mp = p;
nearest_search(0, n, M);
}
int find_range(TPoint p, LL D) {
top = 0;
mp = p;
range_search(0, n, D);
return top;
}
LL dist(const TPoint& a, const TPoint& b) {
LL res = 0;
for (int i = 0; i < K; ++i)
res += sqr<LL>(a.x[i] - b.x[i]);
return res;
}
} KD;
int main() {
int i, n, T;
scanf("%d", &T);
while (T--) {
scanf("%d", &n);
KD.n = n;
KD.K = 2;
for (i = 0; i < n; ++i) {
p[i].read();
KD.kp[i] = p[i];
}
KD.build(0, n);
for (i = 0; i < n; ++i) {
KD.find_nearest(p[i], 2);
printf("%I64d\n", KD.dis2[1]);
}
}
return 0;
}
HDU 2966 模板题
最新推荐文章于 2019-01-15 09:13:00 发布