BZOJ4520: [Cqoi2016]K远点对
Description
已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对。
Input
输入文件第一行为用空格隔开的两个整数 N, K。接下来 N 行,每行两个整数 X,Y,表示一个点
的坐标。1 < = N < = 100000, 1 < = K < = 100, K < = N*(N−1)/2 , 0 < = X, Y < 2^31。
Output
输出文件第一行为一个整数,表示第 K 远点对的距离的平方(一定是个整数)。
Sample Input
10 5
0 0
0 1
1 0
1 1
2 0
2 1
1 2
0 2
3 0
3 1
0 0
0 1
1 0
1 1
2 0
2 1
1 2
0 2
3 0
3 1
Sample Output
9
真是巧啊,BJWC2016也出了这道题,不过那道题是求k小,正解是倍增+随机化圆覆盖。
但这道题用棵kd树乱搞就行啦。
#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; }