CQOI 2016 k远点对
题目大意:n个点,求第k远的点对的距离
KD树裸题
注意要用堆维护第k远
#include<bits/stdc++.h> #define ll unsigned long long #define maxn 100010 using namespace std; inline int read(){ int s=0;char ch=getchar(); for(;ch<'0'||ch>'9';ch=getchar()); for(;ch>='0'&&ch<='9';ch=getchar())s=s*10+ch-'0'; return s; } int n,k,D,root; struct node{ ll d[2],mn[2],mx[2],ls,rs; node(int x=0,int y=0){d[0]=x;d[1]=y;} ll & operator [] (int x){return d[x];} friend bool operator < (node a,node b){return a[D]<b[D];} }a[maxn]; struct K{ ll d; K(ll a=0){d=a;} }; priority_queue<K>Q; bool operator < (K a,K b){return a.d>b.d;} struct KD{ node t[maxn],T; void up(int k){ node l=t[t[k].ls],r=t[t[k].rs]; for(int i=0;i<2;++i){ t[k].mn[i]=t[k].mx[i]=t[k][i]; if(t[k].ls)t[k].mn[i]=min(t[k].mn[i],l.mn[i]),t[k].mx[i]=max(t[k].mx[i],l.mx[i]); if(t[k].rs)t[k].mn[i]=min(t[k].mn[i],r.mn[i]),t[k].mx[i]=max(t[k].mx[i],r.mx[i]); } } int build(int l,int r,int now){ D=now;int mid=(l+r)>>1; nth_element(a+l,a+mid,a+r+1); t[mid]=a[mid]; if(l<mid)t[mid].ls=build(l,mid-1,now^1); if(r>mid)t[mid].rs=build(mid+1,r,now^1); up(mid);return mid; } ll dis(node a,node b){ return (a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1]); } ll get(int k){ if(!k)return 0; ll L=0; L=max(L,dis(T,node(t[k].mn[0],t[k].mn[1]))); L=max(L,dis(T,node(t[k].mn[0],t[k].mx[1]))); L=max(L,dis(T,node(t[k].mx[0],t[k].mn[1]))); L=max(L,dis(T,node(t[k].mx[0],t[k].mx[1]))); return L; } void ask(int k){ if(!k)return; ll dl=get(t[k].ls),dr=get(t[k].rs); ll L=dis(T,t[k]); if(L>Q.top().d){Q.pop();Q.push(K(L));} if(dl>dr){ if(dl>Q.top().d)ask(t[k].ls); if(dr>Q.top().d)ask(t[k].rs); }else{ if(dr>Q.top().d)ask(t[k].rs); if(dl>Q.top().d)ask(t[k].ls); } } void work(){ for(int i=1;i<=n;++i){ T=a[i]; ask(root); } } }kd; int main(){ n=read();k=read();k<<=1; for(int i=1;i<=n;++i) a[i][0]=read(),a[i][1]=read(); root=kd.build(1,n,0); for(int i=1;i<=k;++i)Q.push(K(0)); kd.work(); cout<<Q.top().d<<endl; return 0; }