多维KDtree板子

左右儿子的估价用mn~mx当区间,假设区间里的数都存在;k维轮着做割点

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<cstring>
using namespace std;
const int N=50005;
int n,k,m,rt,w,ans[15];
priority_queue<pair<int,int> >q;
struct qwe
{
int a[5];
int& operator [] (int x)
{
return a[x];
}
bool operator < (const qwe &b) const
{
return a[w]<b.a[w];
}
}a[N],b;
struct KD
{
int ls,rs;
qwe d,mn,mx;
}t[N<<2];
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
void minn(int &x,int y)
{
x>y?x=y:0;
}
void maxx(int &x,int y)
{
x<y?x=y:0;
}
void ud(int ro)
{
if(t[ro].ls)
for(int i=0;i<k;i++)
minn(t[ro].mn[i],t[t[ro].ls].mn[i]),maxx(t[ro].mx[i],t[t[ro].ls].mx[i]);
if(t[ro].rs)
for(int i=0;i<k;i++)
minn(t[ro].mn[i],t[t[ro].rs].mn[i]),maxx(t[ro].mx[i],t[t[ro].rs].mx[i]);
}
int build(int l,int r,int f)
{
if(l>r)
return 0;
w=f;
int mid=(l+r)>>1;
nth_element(a+l,a+mid,a+r+1);
t[mid].mn=t[mid].mx=t[mid].d=a[mid];
t[mid].ls=build(l,mid-1,(f+1)%k);
t[mid].rs=build(mid+1,r,(f+1)%k);
ud(mid);
return mid;
}
int dis(qwe a,qwe b)
{
int r=0;
for(int i=0;i<k;i++)
r+=(a[i]-b[i])*(a[i]-b[i]);
return r;
}
int wk(int ro)
{
int r=0;
for(int i=0;i<k;i++)
{
if(b[i]<t[ro].mn[i])
r+=(t[ro].mn[i]-b[i])*(t[ro].mn[i]-b[i]);
if(b[i]>t[ro].mx[i])
r+=(t[ro].mx[i]-b[i])*(t[ro].mx[i]-b[i]);
}
return r;
}
void ques(int ro,int f)
{
if(!ro)
return;
int dm=dis(t[ro].d,b),dl=t[ro].ls?wk(t[ro].ls):1e9,dr=t[ro].rs?wk(t[ro].rs):1e9;//cerr<<"OK"<<dm<<endl;
if(q.top().first>dm)
q.pop(),q.push(make_pair(dm,ro));
if(dl<dr)
{
if(dl<q.top().first)
ques(t[ro].ls,(f+1)%k);
if(dr<q.top().first)
ques(t[ro].rs,(f+1)%k);
}
else
{
if(dr<q.top().first)
ques(t[ro].rs,(f+1)%k);
if(dl<q.top().first)
ques(t[ro].ls,(f+1)%k);
}
}
int main()
{
while(~scanf("%d%d",&n,&k))
{
memset(t,0,sizeof(t));
for(int i=1;i<=n;i++)
for(int j=0;j<k;j++)
a[i][j]=read();
rt=build(1,n,0);
m=read();
while(m--)
{
for(int i=0;i<k;i++)
b[i]=read();
int s=read();
for(int i=1;i<=s;i++)
q.push(make_pair(1e9,0));
ques(rt,0);
for(int i=1;i<=s;i++)
ans[i]=q.top().second,q.pop();
printf("the closest %d points are:\n",s);
for(int i=s;i>=1;i--)
{
for(int j=0;j<k;j++)
printf("%d ",t[ans[i]].d[j]);
puts("");
}
}
}
return 0;
}

最新文章

  1. Java开发中的高频Collections用法总结与Java平台实现源代码查看方式
  2. java中Commons-fileupload实现上传
  3. STL之map
  4. 【转载]】Microsoft SQL Server, 错误:4064的解决方法
  5. A Step-by-Step Guide to Your First AngularJS App
  6. AOP和IOC个人理解
  7. 静态分析安全测试(SAST)优缺点探析
  8. Linux &amp;amp; Mac curl 命令行使用——POST&amp;amp;GET
  9. VS2010(2012)中使用Unit Testing进行单元测试
  10. 关于一些基础的Java问题的解答(五)
  11. Android P Beta发布!最新版本抢先体验!
  12. JVM TI
  13. VS2017自定义新建模板
  14. Kafka运维填坑(转)
  15. eclipse 工作区空格和回车键显示为乱码
  16. 如何在你的Vue项目配置vux
  17. codeblocks 输入、输出文件的位置
  18. Netty 4.1 Getting Start (翻译) + Demo
  19. Ubuntu Linux下安装Oracle JDK
  20. Java的Guava

热门文章

  1. hadoop2.7.1 nutch2.3 二次开发windows环境
  2. U盘 文件被隐藏解决办法
  3. 基于SpringMVC框架使用ECharts3.0实现堆叠条形图的绘制(下篇)
  4. saltstack安装配置(syndic)
  5. snip_opencv环境配置和测试程序
  6. openwrt gstreamer实例学习笔记(二.gstreamer 的 Element)
  7. 解压Zip
  8. SyntaxError:Strict mode does not allow function declaration in a lexically nested statement.
  9. ios常用到的第三方库
  10. Hihocoder #1098 : 最小生成树二&#183;Kruskal算法 ( *【模板】 )