hdu4347
求与询问点欧几里德距离前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的更多相关文章
- 【hdu4347】The Closest M Points 【KD树模板】
题意 一个k维空间,给出n个点的坐标,给出t个询问,每个询问给出一个点的坐标和一个m.对于每个询问找出跟这个点最接近的m个点 分析 kd树的模板题. #include <cstdio> # ...
- [hdu4347]The Closest M Points(平衡树式kdtree)
解题关键:模板题(结合起来了) #include<iostream> #include<cstdio> #include<cstring> #include< ...
- [hdu4347]The Closest M Points(线段树形式kd-tree)
解题关键:kdtree模板题,距离某点最近的m个点. #include<cstdio> #include<cstring> #include<algorithm> ...
- 【kd-tree】专题总结
感谢orz神·小黑的指导 kd-tree就是用来计算若干维空间k近/远点的数(shou)据(suo)结(you)构(hua) 建树 假设题目是k维的点 第deep层就是用deep%k+1维把所有点分为 ...
随机推荐
- 高性能相关、Scrapy框架
高性能相关 在编写爬虫时,性能的消耗主要在IO请求中,当单进程单线程模式下请求URL时必然会引起等待,从而使得请求整体变慢. import requests def fetch_async(url): ...
- Swagger2 添加HTTP head参数,解决用户是token信息保留
转:http://blog.csdn.net/u014044812/article/details/71473226 大家使用swagger往往会和JWT一起使用,而一般使用jwt会将token放在h ...
- 10个有关String的面试问题
下面是面试中最容易问到的有关String的问题. 1. 如何比较两个字符串?使用"=="还是equals()方法? 简单来讲,"=="测试的是两个对象的引用是否 ...
- MVC网站发布到 IIS
接下来将发布成功的站点部署到iis7.0. 步骤如下: 1. 安装 Microsoft .net FrameWork 4.0安装包(网站开发时候使用的就是.net framework4.0框架); 2 ...
- OpenCV---图像直方图
一:直方图的直接使用 from matplotlib import pyplot as plt def plot_demo(image): print(image.ravel()) plt.hist( ...
- spring boot 2.0.3+spring cloud (Finchley)9、 安全组件Spring Boot Security
官方文档 一.Spring Security介绍 Spring Security是Spring Resource社区的一个安全组件,Spring Security为JavaEE企业级开发提供了全面的安 ...
- uoj311 【UNR #2】积劳成疾
传送门:http://uoj.ac/problem/311 [题解] 这题的期望dp好神奇啊(可能是我太菜了) 由于每个位置都完全一样,所以我们设$f_{i,j}$表示审了连续$i$个位置,最大值不超 ...
- 【BZOJ】1741: [Usaco2005 nov]Asteroids 穿越小行星群
[题意]给定n*n网格,有k个物品,每次可以消灭一行或一列,求消灭掉所有物品的最少操作次数. [算法]二分图最小覆盖 [题解]此题是最小覆盖模型的出处. 将物品的x-y连边建立二分图. 最小覆盖:选择 ...
- 【BZOJ】2631: tree LCT
[题意]给定n个点的树,每个点初始权值为1,m次操作:1.x到y的点加值,2.断一条边并连一条边,保证仍是树,3.x到y的点乘值,4.x到y的点权值和取模.n,m<=10^5. [算法]Link ...
- c语言学习笔记.条件编译.#if,#ifdef,if的区别
最近遇到了,以此做个记录. 条件编译 是C预处理部分的内容. 其判断语句包括 #if #else if #else 以及 #ifdef 和 #endif. 使用 #if (表达式) codes1. ...