求与询问点欧几里德距离前m小的点

其实就是在kdtree询问的时候用优先队列维护一下就好了

好久没写kdtree练一练,注意这道题是多测

 #include<bits/stdc++.h>

 using namespace std;
const int inf=1e4+;
int key,root,n,m,q,k,mxd;
int sqr(int x)
{
return x*x;
} struct point
{
int d[];
friend int dis(point a,point b)
{
int s=;
for (int i=; i<k; i++)
s+=sqr(a.d[i]-b.d[i]);
return s;
}
} po; struct node
{
point nw;
int son[],mi[],mx[];
friend bool operator <(node a,node b)
{
return a.nw.d[key]<b.nw.d[key];
}
}; struct li
{
point a; int l;
friend bool operator <(li a, li b)
{
return a.l<b.l;
}
} mx;
set<li> st; struct kdtree
{
node a[];
void init()
{ a[].son[]=a[].son[]=;
for (int i=; i<; i++)
{
a[].mx[i]=-inf;
a[].mi[i]=inf;
}
}
void update(int x)
{
int l=a[x].son[],r=a[x].son[];
for (int i=; i<k; i++)
{
a[x].mi[i]=min(a[x].nw.d[i],min(a[l].mi[i],a[r].mi[i]));
a[x].mx[i]=max(a[x].nw.d[i],max(a[l].mx[i],a[r].mx[i]));
}
}
int build(int l,int r,int cur)
{
if (l>r) return ;
int m=(l+r)>>;
key=cur; nth_element(a+l,a+m,a+r+);
a[m].son[]=build(l,m-,(cur+)%k);
a[m].son[]=build(m+,r,(cur+)%k);
update(m);
return m;
}
int getmi(int x)
{
int s=;
for (int i=; i<k; i++)
s+=sqr(max(po.d[i]-a[x].mx[i],)+max(a[x].mi[i]-po.d[i],));
return s;
}
void ask(int q)
{
if (!q) return;
int tmp=dis(a[q].nw,po);
st.insert((li){a[q].nw,tmp});
if (st.size()>m)
{
set<li>::iterator it=st.end(); it--;
st.erase(it);
}
mxd=(*st.rbegin()).l;
int l=a[q].son[],r=a[q].son[],dl=,dr=;
if (l) dl=getmi(l);
if (r) dr=getmi(r);
if (dl<dr)
{
if (dl<mxd||st.size()<m) ask(l);
if (dr<mxd||st.size()<m) ask(r);
}
else {
if (dr<mxd||st.size()<m) ask(r);
if (dl<mxd||st.size()<m) ask(l);
}
}
} kd; int main()
{
while (scanf("%d%d",&n,&k)!=EOF)
{
kd.init();
for (int i=; i<=n; i++)
for (int j=; j<k; j++)
scanf("%d",&kd.a[i].nw.d[j]);
root=kd.build(,n,);
scanf("%d",&q);
while (q--)
{
for (int i=; i<k; i++)
scanf("%d",&po.d[i]);
scanf("%d",&m);
st.clear();
kd.ask(root);
printf("the closest %d points are:\n",m);
for (set<li>::iterator it=st.begin(); it!=st.end(); it++)
{
point ans=(*it).a;
for (int i=; i<k; i++)
{
printf("%d",ans.d[i]);
if (i!=k-) printf(" "); else puts("");
}
}
}
}
}

hdu4347的更多相关文章

  1. 【hdu4347】The Closest M Points 【KD树模板】

    题意 一个k维空间,给出n个点的坐标,给出t个询问,每个询问给出一个点的坐标和一个m.对于每个询问找出跟这个点最接近的m个点 分析 kd树的模板题. #include <cstdio> # ...

  2. [hdu4347]The Closest M Points(平衡树式kdtree)

    解题关键:模板题(结合起来了) #include<iostream> #include<cstdio> #include<cstring> #include< ...

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

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

  4. 【kd-tree】专题总结

    感谢orz神·小黑的指导 kd-tree就是用来计算若干维空间k近/远点的数(shou)据(suo)结(you)构(hua) 建树 假设题目是k维的点 第deep层就是用deep%k+1维把所有点分为 ...

随机推荐

  1. 【莫队】【P3834】 【模板】可持久化线段树 1(主席树)

    大家好,我是个毒瘤,我非常喜欢暴力数据结构,于是我就用莫队+分块过了这个题 Solution 发现这个题静态查询资瓷离线,于是考虑莫队. 在这里简单介绍一下莫队: 将所有询问离线后,对原序列分块.按照 ...

  2. Codeforces 937.D Sleepy Game

    D. Sleepy Game time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  3. poj 3764 字典树

    The xor-longest Path Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7332   Accepted: 1 ...

  4. logstash 中配置GeoIP解析地理信息

    logstash中配置的GeoIP的数据库解析ip了,这里是用了开源的ip数据源,用来分析客户端的ip归属地.官网在这里:MAXMIND 下载GeoLiteCity数据库 wget http://ge ...

  5. 「Django」rest_framework学习系列-权限认证

    权限认证:1.项目下utils文件写permissions.py文件 from rest_framework.permissions import BasePermission class SVIPP ...

  6. 前端PHP入门-024-字符串函数-API查看

    数组.字符串和数据库是我们函数里面最.最.最常用的三类函数,数组和数据库我们现在还没有讲到,等讲到的时候我们再来和大家细说. 当然PHP的字符串函数也有很多.我们最常使用的两个系列的字符串: 单字节字 ...

  7. Eclipse 导入Hadoop 2.6.0 源码

    1. 首先前往 官网(Hadoop 2.6 下载地址)上下载Hadoop的源码文件,并解压 2. 事先请确定已经安装好jdk以及maven(Maven安装教程 这是其他人写的一篇博文,保存profil ...

  8. Linux中系统日志

    系统日志的默认路径是:/var/log 下面是几个重要的日志文件的路径及其包含的信息: /var/log/syslog:它和/etc/log/messages日志文件不同,它只记录警告信息,常常是系统 ...

  9. Linux 目录详解 树状目录结构图

    1.树状目录结构图 2./目录 目录 描述 / 第一层次结构的根.整个文件系统层次结构的根目录. /bin/ 需要在单用户模式可用的必要命令(可执行文件):面向所有用户,例如:cat.ls.cp,和/ ...

  10. 浅谈卡特兰数(Catalan number)的原理和相关应用

    一.卡特兰数(Catalan number) 1.定义 组合数学中一个常出现在各种计数问题中出现的数列(用c表示).以比利时的数学家欧仁·查理·卡特兰的名字来命名: 2.计算公式 (1)递推公式 c[ ...