多维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;
}

bzoj 3053: The Closest M Points【KD-tree】的更多相关文章

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

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

  2. BZOJ 3053 The Closest M Points

    [题目分析] 典型的KD-Tree例题,求k维空间中的最近点对,只需要在判断的过程中加上一个优先队列,就可以了. [代码] #include <cstdio> #include <c ...

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

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

  4. 【BZOJ】3053: The Closest M Points(kdtree)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3053 本来是1a的QAQ.... 没看到有多组数据啊.....斯巴达!!!!!!!!!!!!!!!! ...

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

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

  6. BZOJ 3343: 教主的魔法 [分块]【学习笔记】

    3343: 教主的魔法 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1172  Solved: 526[Submit][Status][Discus ...

  7. BZOJ 2330: [SCOI2011]糖果 [差分约束系统] 【学习笔记】

    2330: [SCOI2011]糖果 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 5395  Solved: 1750[Submit][Status ...

  8. BZOJ 1061: [Noi2008]志愿者招募 [单纯形法]【学习笔记】

    1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 3975  Solved: 2421[Submit][Stat ...

  9. BZOJ 4520: [Cqoi2016]K远点对(k-d tree)

    Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 1162  Solved: 618[Submit][Status][Discuss] Descripti ...

随机推荐

  1. window服务器开站点(不通用)

    此文章为记录自己的配置流程,其他人不通用 网站服务器:Windows server 2008 R2 (IIS6.1) + Asp.net 数据库服务器:Windows server 2008 R2 + ...

  2. weex 项目开发(四)项目框架搭建 及 自定义 TabBar 组件

    1.安装  路由模块  及  状态管理模块 npm install vue-router --save npm install vuex --save 2.自定义  TabBar  组件 src / ...

  3. DataGuard备库ORA-01196故障恢复一则

    问题现象 在使用shutdown abort停DataGuard备库后.备库不能open,报ORA-01196错误. 详细例如以下: 发现一备库不能应用日志.查看备库日志没发现报错.怀疑是备库应用日志 ...

  4. Android Studio 一些方便使用的设置

    相信非常多使用Eclipse的朋友,開始用Android Studio都是认为不是特别方便, a:比方怎样使鼠标放到方法上面,就有提示用法; b:怎样设置字体大小,和背景色; c:还有怎么查看Outl ...

  5. PHP生成excel(2)

    现在数据库有一组数据,就是按照年级的分类的学生分数,如何按照年级分类导出到excel表中 1.数据库配置文件config.php <?php $config = array( 'host'=&g ...

  6. Network Booting

    http://en.wikipedia.org/wiki/Network_booting Network booting Network booting is the process of booti ...

  7. Python——类的高级主题

    介绍关于类的一些高级主题,这些是可选的,在Python应用程序中,不会常常遇到. =========================================================== ...

  8. C#高阶与初心:(二)P/Invoke平台调用

    最近某个项目要采集交易终端的信息用于监管,主要厂商给出了API,C++版的...开启hard模式!!! C#调用C++的DLL基本就两种方法:加一个VC++项目包一层,或者使用P/Invoke(平台调 ...

  9. Codeforces Round #253 (Div. 2)——Borya and Hanabi

    题目连接 题意: n表示有n个卡片.每一个卡片有一种颜色和一个数字(共五种不同的颜色和五个不同的数字). 事先知道每种卡片有几张.可是不知道详细的位置. 问须要几次提示就能够知道全部卡片的位置都在哪里 ...

  10. 细数AutoLayout以来UIView和UIViewController新增的相关API

    本文转载至 http://www.itjhwd.com/autolayout-uiview-uiviewcontroller-api/ 细数AutoLayout以来UIView和UIViewContr ...