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

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;
}

  

posted @ 2016-04-14 19:07  wzj_is_a_juruo  阅读(454)  评论(0编辑  收藏  举报