bzoj 3053 HDU 4347 : The Closest M Points  kd树

题目大意:求k维空间内某点的前k近的点。

就是一般的kd树,根据实测发现,kd树的两种建树方式,即按照方差较大的维度分开(建树常数大)或者每一位轮换分割(询问常数大),后者更快也更好些,以后就果断写第二种了。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 510000
#define MAXT MAXN
#define MAXM 6
#define sqr(x) ((qword)(x)*(x))
#define INF 0x3f3f3f3f
typedef long long qword;
int n,m;
struct point
{
int a[MAXM];
qword dis;
void pm()
{
printf("(%d",a[]);
for (int i=;i<m;i++)
printf(",%d",a[i]);
printf(")");
}
void pm2()
{
for (int i=;i<m-;i++)
printf("%d ",a[i]);
printf("%d\n",a[m-]);
}
}pl[MAXN];
bool cmp_0(const point &p1,const point &p2){
return p1.a[]<p2.a[];
}
bool cmp_1(const point &p1,const point &p2){
return p1.a[]<p2.a[];
}
bool cmp_2(const point &p1,const point &p2){
return p1.a[]<p2.a[];
}
bool cmp_3(const point &p1,const point &p2){
return p1.a[]<p2.a[];
}
bool cmp_4(const point &p1,const point &p2){
return p1.a[]<p2.a[];
}
bool cmp_d(const point &p1,const point &p2){
return p1.dis<p2.dis;
}
struct kdt_node
{
int a[MAXM];
int dd,mxp[MAXM],mnp[MAXM];
int ch[];
int ptr;
}kdt[MAXT];
qword get_dis(point &pt,kdt_node &pn)
{
qword ret=;
for (int j=;j<m;j++)
if (pt.a[j]<pn.mnp[j] || pt.a[j]>pn.mxp[j])
ret+=min(sqr(pt.a[j]-pn.mxp[j]),sqr(pt.a[j]-pn.mnp[j]));
return ret;
}
qword get_dis(point &p1,point &p2)
{
qword ret=;
for (int i=;i<m;i++)
ret+=sqr(p1.a[i]-p2.a[i]);
return ret;
}
int topt=;
void Build_kdt(int &now,int l,int r,int d)
{
if (l>r)return;
now=++topt;
int i,j;
for (j=;j<m;j++)kdt[now].mxp[j]=-INF,kdt[now].mnp[j]=INF;
for (i=l;i<=r;i++)
for (j=;j<m;j++)
{
kdt[now].mxp[j]=max(kdt[now].mxp[j],pl[i].a[j]);
kdt[now].mnp[j]=min(kdt[now].mnp[j],pl[i].a[j]);
}
/* double ave[MAXM];
double sqv[MAXM];
memset(ave,0,sizeof(ave));
memset(sqv,0,sizeof(sqv));
for (i=l;i<=r;i++)
for (j=0;j<m;j++)
ave[j]+=pl[i].a[j];
for (j=0;j<m;j++)
ave[j]/=(r-l+1);
for (i=l;i<=r;i++)
for (j=0;j<m;j++)
sqv[j]+=sqr(pl[i].a[j]-ave[j]);
kdt[now].dd=0;
for (j=0;j<m;j++)
if (sqv[j]>sqv[kdt[now].dd])
kdt[now].dd=j;*/
kdt[now].dd=d;
switch (kdt[now].dd)
{
case :nth_element(&pl[l],&pl[(l+r)>>],&pl[r+],cmp_0);break;
case :nth_element(&pl[l],&pl[(l+r)>>],&pl[r+],cmp_1);break;
case :nth_element(&pl[l],&pl[(l+r)>>],&pl[r+],cmp_2);break;
case :nth_element(&pl[l],&pl[(l+r)>>],&pl[r+],cmp_3);break;
case :nth_element(&pl[l],&pl[(l+r)>>],&pl[r+],cmp_4);break;
}
kdt[now].ptr=(l+r)>>;
Build_kdt(kdt[now].ch[],l,((r+l)>>)-,(d+)%m);
Build_kdt(kdt[now].ch[],((r+l)>>)+,r,(d+)%m);
}
point h[MAXN];
int atot;
int toph=;
void search_point(int now,point &pt)
{
if (!now)return ;
qword cdis=get_dis(pt,pl[kdt[now].ptr]);
if (toph<atot || cdis<h[].dis)
{
if (toph==atot)pop_heap(&h[],&h[toph--],cmp_d);
h[toph]=pl[kdt[now].ptr];
h[toph].dis=cdis;
push_heap(&h[],&h[++toph],cmp_d);
}
int t;
if (get_dis(pt,kdt[kdt[now].ch[]]) < get_dis(pt,kdt[kdt[now].ch[]]))
t=;
else
t=;
search_point(kdt[now].ch[t],pt);
if (toph<atot || get_dis(pt,kdt[kdt[now].ch[t^]]) < h[].dis)
{
search_point(kdt[now].ch[t^],pt);
}
}
int main()
{
// freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
int i,j,k,x,y,z;
int root=;
while (~scanf("%d%d",&n,&m))
{
for (i=;i<n;i++)
for (j=;j<m;j++)
scanf("%d",&pl[i].a[j]);
Build_kdt(root,,n-,);
int q;
scanf("%d",&q);
point pt;
for (i=;i<q;i++)
{
for (j=;j<m;j++)
scanf("%d",&pt.a[j]);
scanf("%d",&atot);
search_point(root,pt);
printf("the closest %d points are:\n",atot);
while (toph)
{
pop_heap(&h[],&h[toph--],cmp_d);
}
for (j=;j<atot;j++)
h[j].pm2();
}
}
}

bzoj 3053 HDU 4347 : The Closest M Points kd树的更多相关文章

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

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

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

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

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

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

  4. 数据结构(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 ...

  5. HDU 4347 The Closest M Points (kdTree)

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

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

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

  7. 【HDOJ】4347 The Closest M Points

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

  8. hud 4347 The Closest M Points(KD-Tree)

    传送门 解题思路 \(KD-Tree\)模板题,\(KD-Tree\)解决的是多维问题,它是一个可以储存\(K\)维数据的二叉树,每一层都被一维所分割.它的插入删除复杂度为\(log^2 n\),它查 ...

  9. [hdu4347]The Closest M Points(线段树形式kd-tree)

    解题关键:kdtree模板题,距离某点最近的m个点. #include<cstdio> #include<cstring> #include<algorithm> ...

随机推荐

  1. yum 命令提示语法错误

    1. 问题信息 SyntaxError: invalid syntax 2. 问题原因 升级python版本导致 3. 解决方法 vi /usr/bin/yum 将#!/usr/bin/python ...

  2. 下载好一个android软件之后,怎样自动提示安装?

    最近在做毕设,里面牵涉到版本更新,当有新版本时可以下载新版本,下载完成之后提示安装.那么怎么实现下载完成之后提示安装呢? 直接上代码吧: File mFile = new File(Environme ...

  3. flex脚本的申明

    //脚本申明的格式 <fx:Script>    <![CDATA[            ]]></fx:Script> //程序完成的时候自动调用的事件 cre ...

  4. java.lang.NoClassDefFoundError: com.nostra13.universalimageloader.core.DisplayImageOptions$Builder

    今天在使用Universal-image-loader开源插件的时候,一直出现了这么个错误.原因是在ADT22版本中导入jar包的方式不对. 正确的导入jar包方式: 在adt17的版本之后,导入第三 ...

  5. Magento Block设计分析(深入分析)

    Magento中Block是一个很重要的组件,它在Block中充当非常重要的角色,下面我们来分析一下Magento中Block是怎样设计的,我们应该怎样使用这个重要的角色. 1.Magento Blo ...

  6. 走进React的学习之路

    GIT: 代码管理.https://git-scm.com/book/zh/v2 ES6: http://www.infoq.com/cn/minibooks/ES6-in-Depth Webpack ...

  7. .NET 统一用户管理 -- 统一鉴权

    统一鉴权 目的 为什么要统一鉴权了,每一个业务系统几乎都离不开,用户,角色,权限 这个 3个基础功能,为了避免各个系统各自去开发一套权限管理等基础功能,也同时轻松管理每个用户的全部权限. 怎么做   ...

  8. ASP.NET Identity 用户注册相关设定

    此部分可以在 Web项目中的App_Start目录下的 IdentityConfig.cs 文件进行设置. 1.配置密码的验证逻辑 manager.PasswordValidator = new Pa ...

  9. 向SQL2008R2导入Acess、excel数据

    一:导入Access数据 1.在sql2008查询分析 器中输入如下查询语句能查出access中的数据 SELECT * FROM OpenDataSource( 'Microsoft.Jet.OLE ...

  10. Python入门 学习笔记 (一)

    原文地址:http://www.cnblogs.com/lujianwenance/p/5939786.html 说到学习一门语言第一步就是先选定使用的工具(环境).因为本人是个小白,所以征求了一下同 ...