已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对。
【题目描述】
已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对。
输出文件第一行为一个整数,表示第 K 远点对的距离的平方(一定是个整数)。
KD-tree裸题
用小根堆维护当前答案,query判断范围时与堆顶元素比较
/* --------------
user Vanisher
problem bzoj-4520
----------------*/
# include
# define ll long long
# define inf 6e9
# define N 100010
using namespace std;
priority_queue ,greater > hp;
ll read(){
ll tmp=0, fh=1; char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();}
while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar();}
return tmp*fh;
}
struct point{
ll x,y;
}p[N];
struct node{
ll lx,ly,rx,ry,pl,pr,tag;
point num;
}T[N];
ll place,n,k;
double sqr(double x){return x*x;}
void change(ll now){
T[now].lx=min(T[now].num.x,min(T[T[now].pl].lx,T[T[now].pr].lx));
T[now].rx=max(T[now].num.x,max(T[T[now].pl].rx,T[T[now].pr].rx));
T[now].ly=min(T[now].num.y,min(T[T[now].pl].ly,T[T[now].pr].ly));
T[now].ry=max(T[now].num.y,max(T[T[now].pl].ry,T[T[now].pr].ry));
}
bool cmpx(point x, point y){return x.xr) return 0;
ll now=++place,mid=(l+r)/2;
double sumx=0,sumy=0,deltax=0,deltay=0;
for (ll i=l; i<=r; i++)
sumx=sumx+p[i].x, sumy=sumy+p[i].y;
sumx=sumx/(r-l+1); sumy=sumy/(r-l+1);
for (ll i=l; i<=r; i++){
deltax=deltax+sqr(p[i].x-sumx);
deltay=deltay+sqr(p[i].y-sumy);
}
if (deltax>deltay){
T[now].tag=0;
nth_element(p+l,p+mid,p+r+1,cmpx);
}
else{
T[now].tag=1;
nth_element(p+l,p+mid,p+r+1,cmpy);
}
T[now].num=p[mid];
T[now].pl=build(l,mid-1); T[now].pr=build(mid+1,r);
change(now);
return now;
}
ll distmx(ll now, point x){
ll num=sqr(max(abs(T[now].lx-x.x),abs(T[now].rx-x.x)));
num=num+sqr(max(abs(T[now].ly-x.y),abs(T[now].ry-x.y)));
return num;
}
void solve(ll now, point x){
if (now==0) return;
ll d0=sqr(T[now].num.x-x.x)+sqr(T[now].num.y-x.y),d1,d2;
if (d0>hp.top()){
hp.pop(); hp.push(d0);
}
if (T[now].pl!=0) d1=distmx(T[now].pl,x); else d1=-1;
if (T[now].pr!=0) d2=distmx(T[now].pr,x); else d2=-1;
if (d1>d2){
if (d1>hp.top()) solve(T[now].pl,x);
if (d2>hp.top()) solve(T[now].pr,x);
}
else {
if (d2>hp.top()) solve(T[now].pr,x);
if (d1>hp.top()) solve(T[now].pl,x);
}
}
int main(){
n=read(); k=read();
T[0].ly=T[0].lx=inf; T[0].rx=T[0].ry=-inf;
for (ll i=1; i<=2*k; i++) hp.push(-1);
for (ll i=1; i<=n; i++)
p[i].x=read(), p[i].y=read();
ll rt=build(1,n);
for (ll i=1; i<=n; i++)
solve(rt,p[i]);
printf("%lld\n",hp.top());
return 0;
}