bzoj 4520: [Cqoi2016]K远点对(KD-tree)

4520: [Cqoi2016]K远点对

Time Limit: 30 Sec   Memory Limit: 512 MB
Submit: 628   Solved: 334
[ Submit][ Status][ Discuss]

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

HINT

Source

[ Submit][ Status][ Discuss]

题解:KD-tree

建立KD-tree,枚举每个节点更新答案。因为这样每个点对会被计算两次,所以将k*=2

#include
#include
#include
#include
#include
#include
#define LL long long 
#define N 200003
using namespace std;
int root,cmpd,n,m,x,y;
struct data
{
	int d[2],mx[2],mn[2],l,r;
}tr[N];
priority_queue,greater > p;
int cmp(data a,data b)
{
	return a.d[cmpd]mid) tr[mid].r=build (mid+1,r,d^1);
	 update(mid);
	 return mid;
}
LL pow(int x)
{
	return (LL)x*(LL)x;
}
LL dist(int now)
{
	LL t=0;
	t+=max(pow(tr[now].mx[0]-x),pow(tr[now].mn[0]-x));
	t+=max(pow(tr[now].mx[1]-y),pow(tr[now].mn[1]-y));
	return t;
}
void query(int now)
{
	LL d0=pow(tr[now].d[0]-x)+pow(tr[now].d[1]-y);
	if (p.size()t) {
			p.pop();
			p.push(d0);
		}		
	}
	LL dl=-1,dr=-1;
	if(tr[now].l) dl=dist(tr[now].l);
	if(tr[now].r) dr=dist(tr[now].r);
	if (dl>dr) {
		if (dl!=-1)
		 if (p.size()



你可能感兴趣的:(KD-tree)