传送门

解题思路

  \(KD-Tree\)模板题,\(KD-Tree\)解决的是多维问题,它是一个可以储存\(K\)维数据的二叉树,每一层都被一维所分割。它的插入删除复杂度为\(log^2 n\),它查询最近点对的复杂度为\(O(n^{\frac{k-1}{k}}\),\(k\)代表维数。用堆维护最近点,查询时就先找到它属于的区域,然后回溯时判断一下它到父节点的距离和堆顶的大小,如果比堆顶还大就不递归它的兄弟节点。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm> using namespace std;
const int N=50005; inline int rd(){
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) f=ch=='-'?0:1,ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return f?x:-x;
} inline int pw(int x){
return x*x;
} int n,q,K,t; struct Node{
int a[7];
void init() {
memset(a,0,sizeof(a));
}
friend bool operator<(const Node A,const Node B){
return A.a[t]<B.a[t];
}
}node[N],pt[N<<2],ans[25];
priority_queue<pair<double,Node> > Q; struct KD_Tree{
#define mid ((l+r)>>1)
int end[N<<2];
void build(int x,int l,int r,int dep){
if(l>r) return; t=dep%K;
end[x]=0; end[x<<1]=end[x<<1|1]=1;
nth_element(node+l,node+mid,node+r+1);
pt[x]=node[mid];
build(x<<1,l,mid-1,dep+1); build(x<<1|1,mid+1,r,dep+1);
}
void query(int x,int dep,int lim,Node now){
if(end[x]) return;
pair<double,Node> tmp=make_pair(0,pt[x]);
for(int i=0;i<K;i++) tmp.first+=pw(pt[x].a[i]-now.a[i]);
int ls=x<<1,rs=x<<1|1,t=dep%K,flag=0;
if(now.a[t]>=pt[x].a[t]) swap(ls,rs);
if(!end[ls]) query(ls,dep+1,lim,now);
if(Q.size()<lim) Q.push(tmp),flag=1;
else {
if(Q.top().first>tmp.first) Q.pop(),Q.push(tmp);
if(pw(pt[x].a[t]-now.a[t])<Q.top().first) flag=1;
}
if(!end[rs] && flag) query(rs,dep+1,lim,now);
}
#undef mid
}tree; int main(){
while(~scanf("%d%d",&n,&K)){
for(int i=1;i<=n;i++)
for(int j=0;j<K;j++) node[i].a[j]=rd();
tree.build(1,1,n,0);
for(q=rd();q;q--){
Node now; now.init();
for(int i=0;i<K;i++) now.a[i]=rd();
int t=rd(); tree.query(1,0,t,now);
for(int i=1;!Q.empty();i++)
ans[i]=Q.top().second,Q.pop();
printf("the closest %d points are:\n",t);
for(int i=t;i;i--){
printf("%d",ans[i].a[0]);
for(int j=1;j<K;j++)
printf(" %d",ans[i].a[j]);
putchar('\n');
}
}
}
return 0;
}

hud 4347 The Closest M Points(KD-Tree)的更多相关文章

  1. bzoj 3053 HDU 4347 : The Closest M Points kd树

    bzoj 3053 HDU 4347 : The Closest M Points  kd树 题目大意:求k维空间内某点的前k近的点. 就是一般的kd树,根据实测发现,kd树的两种建树方式,即按照方差 ...

  2. BZOJ 3053: The Closest M Points(K-D Tree)

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1235  Solved: 418[Submit][Status][Discuss] Descripti ...

  3. hdu 4347 The Closest M Points (kd树)

    版权声明:本文为博主原创文章,未经博主允许不得转载. hdu 4347 题意: 求k维空间中离所给点最近的m个点,并按顺序输出  . 解法: kd树模板题 . 不懂kd树的可以先看看这个 . 不多说, ...

  4. hdu 4347 The Closest M Points(KD树)

    Problem - 4347 一道KNN的题.直接用kd树加上一个暴力更新就撸过去了.写的时候有一个错误就是搜索一边子树的时候返回有当前层数会被改变了,然后就直接判断搜索另一边子树,搞到wa了半天. ...

  5. 数据结构(KD树):HDU 4347 The Closest M Points

    The Closest M Points Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 98304/98304 K (Java/Ot ...

  6. 【HDOJ】4347 The Closest M Points

    居然是KD解. /* 4347 */ #include <iostream> #include <sstream> #include <string> #inclu ...

  7. HDU 4347 - The Closest M Points - [KDTree模板题]

    本文参考: https://www.cnblogs.com/GerynOhenz/p/8727415.html kuangbin的ACM模板(新) 题目链接:http://acm.hdu.edu.cn ...

  8. BZOJ3053:The Closest M Points(K-D Teee)

    Description The course of Software Design and Development Practice is objectionable. ZLC is facing a ...

  9. HDU 4347 The Closest M Points (kdTree)

    赤果果的kdTree. 学习传送门:http://www.cnblogs.com/v-July-v/archive/2012/11/20/3125419.html 其实就是二叉树的变形 #includ ...

随机推荐

  1. 字符串 映射相应的 函数 字符串驱动技术—— MethodAddress , MethodName , ObjectInvoke

    http://blog.csdn.net/qustdong/article/details/7267258 字符串驱动技术—— MethodAddress , MethodName , ObjectI ...

  2. js-禁止长页面滚动

    标题的需求问题其实我经常遇到.尤其是在碰到页面同时出现有视频及弹层的情况. 当然我说的问题皆是针对微信H5开发的哈 IOS中,视频播放,弹层出现时,视频在弹层的下面,不会出现问题: 安卓手机中,完了, ...

  3. react 之 flux

    [WangQi]---flux---[react]   一.什么是Flux Flux 是一种架构思想,专门解决软件的结构问题.它跟MVC 架构是同一类东西,但是更加简单和清晰. 二.flux的基本概念 ...

  4. 2019年华南理工大学软件学院ACM集训队选拔赛 Round1

    TIps: 1.所有代码中博主使用了scanf和printf作为输入输出  2.代码中使用了define LL long long 所以在声明变量的时候 LL其实就等价于long long 希望这两点 ...

  5. SCUT - 11 - 被钦定的选手 - 质因数分解

    https://scut.online/p/11 T了好多次,还想用mutimap暴力分解每个数的质因数.后来记录每个数的最小质因子过了. #include <bits/stdc++.h> ...

  6. LeetCode103. 二叉树的锯齿形层次遍历

    103. 二叉树的锯齿形层次遍历 描述 给定一个二叉树,返回其节点值的锯齿形层次遍历.(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行). 示例 例如,给定二叉树: [3,9,2 ...

  7. Log4Net 之走进Log4Net (四)

    原文:Log4Net 之走进Log4Net (四) 一.Log4net的结构 log4net 有四种主要的组件,分别是Logger(记录器), Repository(库), Appender(附着器) ...

  8. python学习笔记(11):文件的访问与函数式编程

    一.文本文件读写的三种方法 1.直接读入 file1 = open('E:/hello/hello.txt') file2 = open('output.txt','w') #w是可写的文件 whil ...

  9. JavaScript数组增删方法总结

    数组是JavaScript中常见的一个对象,在这篇文章中主要整理数组增删改查方面的相关操作方法. 首先我们创建一个数组 添加元素: push(elment) 从后面添加元素,返回数组的长度   uns ...

  10. Vue实现点击li变色

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...