参考博客
http://www.cnblogs.com/LyonLys/archive/2013/05/26/hdu_2966_Lyon.html
kd-tree的理解可以参见百度百科:
http://baike.baidu.com/link?url=tBsrmpSUW9V0qcVCzBCM52ZLqN8s7NaRV89a2DJhU-pOttVq2u29Gw7Rt4CoFL6RN9sJ2VnvsLtD5yvDp3xljq
//题意:给定n个点,查找n个点所对应的最近点的距离的平方。
// E - In case of failure HDU - 2966
// kd-tree
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<iostream>
#include<queue>
#include<stack>
#include<cmath>
#include<cstring>
using namespace std;
const int maxn=100000+100;
typedef long long LL;
struct Point{
int x[2];
};
Point po[maxn],ori[maxn];
int cur,dim;
bool cmp(Point a,Point b)
{
return a.x[cur]<b.x[cur];
}
int n,ans;
void build(int L,int R,int depth)
{
if(L>=R) return;
int M=(L+R)>>1;
cur=depth%dim;
nth_element(po+L,po+M,po+R+1,cmp);
build(L,M-1,depth+1);
build(M+1,R,depth+1);
}
const LL INF=2*1e18;
LL sqr(int x)
{
return 1LL*x*x;
}
LL dist(Point a,Point b)
{
LL res=0;
for(int i=0;i<dim;i++){
res+=sqr(a.x[i]-b.x[i]);
}
return res?res:INF;
}
LL find(Point x,int L,int R,int depth)
{
int cur=depth%dim;
if(L>=R){
if(L==R) return dist(x,po[L]);
else return INF;
}
int M=(L+R)>>1;
LL res=dist(x,po[M]);
LL tmp;
if(x.x[cur]<po[M].x[cur]){
tmp=find(x,L,M-1,depth+1);
if(tmp>sqr(x.x[cur]-po[M].x[cur])){
tmp=min(tmp,find(x,M+1,R,depth+1));
}
}
else{
tmp=find(x,M+1,R,depth+1);
if(tmp>sqr(x.x[cur]-po[M].x[cur])){
tmp=min(tmp,find(x,L,M-1,depth+1));
}
}
return min(res,tmp);
}
void solve()
{
scanf("%d",&n);
int x,y;
for(int i=1;i<=n;i++){
scanf("%d %d",&x,&y);
po[i].x[0]=x;
po[i].x[1]=y;
ori[i]=po[i];
}
cur=0;
dim=2;
build(1,n,0);
for(int i=1;i<=n;i++){
printf("%lld\n",find(ori[i],1,n,0));
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
solve();
}
return 0;
}