BZOJ4520: [Cqoi2016]K远点对

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

题解Here!

$K-D\ Tree$的板子题了。。。
不多说。
附代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#define MAXN 101000
#define MAX (1LL<<60)
using namespace std;
priority_queue< long long,vector<long long>,greater<long long> > heap;
int n,m,root;
bool sort_flag=false;
struct Point{
	long long x,y;
	friend bool operator <(const Point &p,const Point &q){
		if(sort_flag)return p.y<q.y;
		return p.x<q.x;
	}
}point[MAXN],now;
struct Tree{
	Point point;
	long long minx,miny,maxx,maxy;
	int lson,rson;
}a[MAXN];
inline long long read(){
	long long date=0;char c=0;
	while(c<'0'||c>'9')c=getchar();
	while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
	return date;
}
inline long long get_dis(const Point &p,const Point &q){
	return (p.x-q.x)*(p.x-q.x)+(p.y-q.y)*(p.y-q.y);
}
inline void pushup(int rt){
	int lson=a[rt].lson,rson=a[rt].rson;
	a[rt].maxx=max(a[rt].maxx,max(a[lson].maxx,a[rson].maxx));
	a[rt].maxy=max(a[rt].maxy,max(a[lson].maxy,a[rson].maxy));
	a[rt].minx=min(a[rt].minx,min(a[lson].minx,a[rson].minx));
	a[rt].miny=min(a[rt].miny,min(a[lson].miny,a[rson].miny));
}
void buildtree(int l,int r,int &rt,int flag){
	int mid=l+r>>1;
	rt=mid;
	sort_flag=flag;
	nth_element(point+l,point+mid,point+r+1);
	a[rt].point=point[mid];
	a[rt].minx=a[rt].maxx=point[mid].x;
	a[rt].miny=a[rt].maxy=point[mid].y;
	if(l<mid)buildtree(l,mid-1,a[rt].lson,flag^1);
	if(mid<r)buildtree(mid+1,r,a[rt].rson,flag^1);
	pushup(rt);
}
inline long long max_dis(int rt){
	long long x,y;
	x=max(abs(now.x-a[rt].minx),abs(now.x-a[rt].maxx));
	y=max(abs(now.y-a[rt].miny),abs(now.y-a[rt].maxy));
	return (x*x+y*y);
}
void query(int rt){
	long long dis=get_dis(a[rt].point,now),ldis=-MAX,rdis=-MAX;
	if(dis>heap.top()){
		heap.pop();
		heap.push(dis);
	}
	if(a[rt].lson)ldis=max_dis(a[rt].lson);
	if(a[rt].rson)rdis=max_dis(a[rt].rson);
	if(ldis>rdis){
		if(ldis>heap.top())query(a[rt].lson);
		if(rdis>heap.top())query(a[rt].rson);
	}
	else{
		if(rdis>heap.top())query(a[rt].rson);
		if(ldis>heap.top())query(a[rt].lson);
	}
}
void work(){
	for(int i=1;i<=n;i++){
		now=point[i];
		query(root);
	}
	printf("%lld\n",heap.top());
}
void init(){
	n=read();m=read();
	a[0].minx=a[0].miny=MAX;
	a[0].maxx=a[0].maxy=-MAX;
	for(int i=1;i<=n;i++){point[i].x=read();point[i].y=read();}
	buildtree(1,n,root,0);
	for(int i=1;i<=2*m;i++)heap.push(0);
}
int main(){
	init();
	work();
	return 0;
}

 

posted @ 2019-04-04 21:16  符拉迪沃斯托克  阅读(198)  评论(0编辑  收藏  举报
Live2D