zoukankan      html  css  js  c++  java
  • 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
    ",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;
    }
    
  • 相关阅读:
    Arcgis地理处理工具案例教程——批量提取多个栅格的范围边界矢量
    win10 windows10自动修复系统
    ArcGIS案例教程—E00格式批量导入成要素类
    Python正则表达式多行匹配问题
    学习ArcGIS开发的途径有哪些
    Arcgis空间分析案例教程——计算空间分布范围
    ArcGIS地理建模批处理教程——批量添加文件名作为字段值
    ArcGIS地理建模批处理教程——批量去除Z值和M值
    华为NM存储卡与Micro SD存储卡对比分析
    EDT
  • 原文地址:https://www.cnblogs.com/Yangrui-Blog/p/10657115.html
Copyright © 2011-2022 走看看