hdu 2966 In case of failure(KD-tree)

题目链接:hdu 2966 In case of failure

题意:

给你n个点,让你输出每个点到最近点的欧式距离。

题解:

KD-树裸题,板子抄的鸟神的。

 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=(a);i<=(b);++i)
 3 using namespace std;
 4 using ll=long long;
 5 
 6 namespace KD_Tree{
 7     const int N=1e5+7,DI=2;
 8     struct Node{
 9         int p[DI],f,l,r,mx[DI],mi[DI];
10         int operator[](const int&idx)const{return p[idx];}
11         void in(int idx,int *v){f=idx;F(i,0,DI-1)p[i]=v[i];}
12         void up(Node&a){
13             F(i,0,DI-1){
14                 mi[i]=min(mi[i],a.mi[i]);
15                 mx[i]=max(mx[i],a.mx[i]);
16             }
17         }
18     }T[N];
19     int idx[N],cmpd,root;
20     
21     bool cmp(const Node&a,const Node&b){return a[cmpd]<b[cmpd];}
22     void up(int x){
23         if(T[x].l)T[x].up(T[T[x].l]);
24         if(T[x].r)T[x].up(T[T[x].r]);
25     }
26     int build(int l,int r,int d=0,int f=0)
27     {
28         int mid=l+r>>1;
29         cmpd=d%DI,nth_element(T+l,T+mid,T+r+1,cmp);
30         idx[T[mid].f]=mid,T[mid].f=f;
31         F(i,0,DI-1)T[mid].mi[i]=T[mid].mx[i]=T[f][i];
32         T[mid].l=l!=mid?build(l,mid-1,d+1,mid):0;
33         T[mid].r=r!=mid?build(mid+1,r,d+1,mid):0;
34         return up(mid),mid;
35     }
36     ll dist(ll x,ll y=0){return x*x+y*y;}
37     ll query(ll x,ll y,ll&ans,int rt=root,int d=0)
38     {
39         ll tmp=dist(x-T[rt][0],y-T[rt][1]);
40         if(tmp)ans=min(ans,tmp);
41         if(T[rt].l&&T[rt].r)
42         {
43             bool is=!d?(x<=T[rt][0]):(y<=T[rt][1]);
44             ll dis=!d?dist(x-T[rt][0]):dist(y-T[rt][1]);
45             query(x,y,ans,is?T[rt].l:T[rt].r,!d);
46             if(dis<ans)query(x,y,ans,is?T[rt].r:T[rt].l,!d);
47         }
48         else if(T[rt].l)query(x,y,ans,T[rt].l,!d);
49         else if(T[rt].r)query(x,y,ans,T[rt].r,!d);
50     }
51 };
52 using namespace KD_Tree;
53 int t,n;
54 
55 int main(){
56     scanf("%d",&t);
57     while(t--)
58     {
59         scanf("%d",&n);
60         F(i,1,n)
61         {
62             int x[2];
63             scanf("%d%d",x,x+1);
64             T[i].in(i,x);
65         }
66         root=build(1,n);
67         F(i,1,n)
68         {
69             ll ans=1ll<<61;
70             query(T[idx[i]][0],T[idx[i]][1],ans);
71             printf("%lld\n",ans);
72         }
73     }
74     return 0;
75 }
View Code

 

转载于:https://www.cnblogs.com/bin-gege/p/7299644.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值