已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对。
标签:
已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对。
输出文件第一行为一个整数,表示第 K 远点对的距离的平方(一定是个整数)。
#include<cstdio>
#include<cstring>
#include<cctype>
#include<queue>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
using namespace std;
const int BufferSize=1<<16;
char buffer[BufferSize],*head,*tail;
inline char Getchar() {
if(head==tail) {
int l=fread(buffer,1,BufferSize,stdin);
tail=(head=buffer)+l;
}
return *head++;
}
inline int read() {
int x=0,f=1;char c=Getchar();
for(;!isdigit(c);c=Getchar()) if(c==‘-‘) f=-1;
for(;isdigit(c);c=Getchar()) x=x*10+c-‘0‘;
return x*f;
}
typedef long long ll;
const int maxn=100010;
const ll inf=1ll<<60;
struct Node {
ll x[2],mn[2],mx[2];
int lc,rc;
}T[maxn],A,B[maxn];
int n,k,ToT;
priority_queue<ll> Q;
ll getmx(Node &o) {
ll X=max(abs(o.mn[0]-A.x[0]),abs(o.mx[0]-A.x[0])),Y=max(abs(o.mn[1]-A.x[1]),abs(o.mx[1]-A.x[1]));
return X*X+Y*Y;
}
void relax(Node &o) {
ll val=(o.x[0]-A.x[0])*(o.x[0]-A.x[0])+(o.x[1]-A.x[1])*(o.x[1]-A.x[1]);
if(val>-Q.top()) Q.pop(),Q.push(-val);
}
void query(int& o,int c) {
if(!o) return;
if(getmx(T[o])<=-Q.top()) return;
relax(T[o]);query(T[o].lc,c^1);query(T[o].rc,c^1);
}
void update(Node &o) {
int lc=o.lc,rc=o.rc;
o.mn[0]=min(o.x[0],min(T[lc].mn[0],T[rc].mn[0]));
o.mn[1]=min(o.x[1],min(T[lc].mn[1],T[rc].mn[1]));
o.mx[0]=max(o.x[0],max(T[lc].mx[0],T[rc].mx[0]));
o.mx[1]=max(o.x[1],max(T[lc].mx[1],T[rc].mx[1]));
}
void insert(int& o,int c) {
if(!o) {
o=++ToT;
T[o]=A;
T[o].mn[0]=T[o].mx[0]=T[o].x[0];
T[o].mn[1]=T[o].mx[1]=T[o].x[1];
return;
}
if(!c) insert(A.x[0]<=T[o].x[0]?T[o].lc:T[o].rc,c^1);
else insert(A.x[1]<=T[o].x[1]?T[o].lc:T[o].rc,c^1);
update(T[o]);
}
int main() {
T[0].mn[0]=T[0].mn[1]=inf;
T[0].mx[0]=T[0].mx[1]=-inf;
n=read();k=read();int rt=0;
rep(i,1,k) Q.push(0);
rep(i,1,n) B[i].x[0]=read(),B[i].x[1]=read();
random_shuffle(B+1,B+n+1);
rep(i,1,n) {
A=B[i];
query(rt,0);insert(rt,0);
}
printf("%lld\n",-Q.top());
return 0;
}
标签:
原文地址:http://www.cnblogs.com/wzj-is-a-juruo/p/5392313.html