• BZOJ 2626 & KDtree


    题意:

      二维平面n个点 每次给出一个点询问距离第k小的点.

    SOL:

      kdtree裸题,抄了一发别人的模板...二维割起来还是非常显然的.膜rzz的论文.

      不多说了吧....

    Code:

      

    /*==========================================================================
    # Last modified: 2016-03-18 20:26
    # Filename: 2626.cpp
    # Description: 
    ==========================================================================*/
    #define me AcrossTheSky 
    #include <cstdio> 
    #include <cmath> 
    #include <ctime> 
    #include <string> 
    #include <cstring> 
    #include <cstdlib> 
    #include <iostream> 
    #include <algorithm> 
      
    #include <set> 
    #include <map> 
    #include <stack> 
    #include <queue> 
    #include <vector> 
     
    #define lowbit(x) (x)&(-x) 
    #define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++) 
    #define FORP(i,a,b) for(int i=(a);i<=(b);i++) 
    #define FORM(i,a,b) for(int i=(a);i>=(b);i--) 
    #define ls(a,b) (((a)+(b)) << 1) 
    #define rs(a,b) (((a)+(b)) >> 1) 
    #define getlc(a) ch[(a)][0] 
    #define getrc(a) ch[(a)][1] 
     
    #define maxn 100000 
    #define maxm 100000 
    #define pi 3.1415926535898 
    #define _e 2.718281828459 
    #define INF 1070000000 
    using namespace std; 
    typedef long long LL; 
    typedef unsigned long long uLL; 
     
    template<class T> inline 
    void read(T& num) { 
        bool start=false,neg=false; 
        char c; 
        num=0; 
        
    	while((c=getchar())!=EOF) { 
            if(c=='-') start=neg=true; 
            else if(c>='0' && c<='9') { 
                start=true; 
                num=num*10+c-'0'; 
            } else if(start) break; 
        } 
        if(neg) num=-num; 
    } 
    /*==================split line==================*/
    int flag;
    struct node{
     	int id;
       	LL x,y;
       	void in(int i){
       		read(x); read(y);
       		id=i;
       	}
       	bool operator<(const node& a)const{	
       		if(!flag) return x<a.x;
       		return y<a.y;
       	}
    }p[maxn];
    LL sqr(LL x){return x*x;}
    LL dist(node a,node b){return sqr(a.x-b.x)+sqr(a.y-b.y);}
         
    struct cpt{
      	LL dis;
      	int id; 
       	bool operator<(const cpt &a)const{
       		if(dis!=a.dis) return dis>a.dis;
       		return id<a.id;
       	}
    };
         
    priority_queue<cpt> q;	
         
    struct KD{	
       	LL minv[2],maxv[2];
       	LL dis(node p){	
       		LL x=max(abs(p.x-minv[0]),abs(p.x-maxv[0]));
       		LL y=max(abs(p.y-minv[1]),abs(p.y-maxv[1]));
       		return sqr(x)+sqr(y);
      	}
       	KD operator+(const KD &a){
       		KD c;	
       		c.minv[0]=min(minv[0],a.minv[0]);
       		c.minv[1]=min(minv[1],a.minv[1]);
       		c.maxv[0]=max(maxv[0],a.maxv[0]);
       		c.maxv[1]=max(maxv[1],a.maxv[1]);
       		return c;
       	}
    };
         
    struct KDtree{
        node p;KD c;	
    }tree[maxn];
    int n,m,kth,ch[maxn][2],tot;
    
    int build(int l,int r,int k){
    	int x=++tot;
    	flag=k;
    	int mid=rs(l,r); nth_element(p+l,p+mid,p+r+1);
    	tree[x].p=p[mid];
    	tree[x].c.minv[0]=tree[x].c.maxv[0]=tree[x].p.x;
    	tree[x].c.minv[1]=tree[x].c.maxv[1]=tree[x].p.y;
    	if (l<=mid-1){
    		ch[x][0]=build(l,mid-1,k^1);
    		tree[x].c=tree[x].c+tree[ch[x][0]].c;
    	}
    	if (mid+1<=r){
    		ch[x][1]=build(mid+1,r,k^1);
    		tree[x].c=tree[x].c+tree[ch[x][1]].c;
    	}
    	return x;
    }
    void ask(int x,node a,int k){
    	cpt tmp=(cpt){dist(tree[x].p,a),tree[x].p.id};
    	int lc=ch[x][0],rc=ch[x][1];
    	flag=k;
    	if (q.size()<kth) q.push(tmp);
    	else if (tmp<q.top()){q.pop(); q.push(tmp);}
    	if (a<tree[x].p) swap(lc,rc);
    	if (lc && (q.size()<kth || tree[lc].c.dis(a)>=q.top().dis)) 
    		ask(lc,a,k^1);
    	if (rc && (q.size()<kth || tree[rc].c.dis(a)>=q.top().dis))
    		ask(rc,a,k^1);
    }
    int main(){
    	//freopen("a.in","r",stdin);
    	read(n);
    	FORP(i,1,n) p[i].in(i);
    	build(1,n,0);
    	int m; read(m);
    	FORP(i,1,m){
    		node a; a.in(i);
    		read(kth);
    		while (!q.empty()) q.pop();
    		ask(1,a,0);
    		printf("%d
    ",q.top().id);
    	}
    }
    
  • 相关阅读:
    base64这种编码的意义
    玩2k16
    http://riddle.arthurluk.net walkthrough
    sshfs
    其它技术名称解释
    解决Apache日志"internal dummy connection"方法
    Aliyun OSS Nginx proxy module(阿里云OSS Nginx 签名代理模块)
    php-imagick扩展
    phpinfo空白
    Docker数据管理-数据卷 data volumes和数据卷容器data volumes containers的使用详解
  • 原文地址:https://www.cnblogs.com/YCuangWhen/p/5295078.html
Copyright © 2020-2023  润新知