BZOJ3053:The Closest M Points(K-D Teee)
Description
The course of Software Design and Development Practice is objectionable. ZLC is facing a serious problem .There are many points in K-dimensional space .Given a point. ZLC need to find out the closest m points. Euclidean distance is used as the distance metric between two points. The Euclidean distance between points p and q is the length of the line segment connecting them.In Cartesian coordinates, if p = (p1, p2,..., pn) and q = (q1, q2,..., qn) are two points in Euclidean n-space, then the distance from p to q, or from q to p is given by:
D(p,q)=D(q,p)=sqrt((q1-p1)^2+(q2-p2)^2+(q3-p3)^2…+(qn-pn)^2
Can you help him solve this problem?
软工学院的课程很讨厌!ZLC同志遇到了一个头疼的问题:在K维空间里面有许多的点,对于某些给定的点,ZLC需要找到和它最近的m个点。
(这里的距离指的是欧几里得距离:D(p, q) = D(q, p) = sqrt((q1 - p1) ^ 2 + (q2 - p2) ^ 2 + (q3 - p3) ^ 2 + ... + (qn - pn) ^ 2)
ZLC要去打Dota,所以就麻烦你帮忙解决一下了……
【Input】
第一行,两个非负整数:点数n(1 <= n <= 50000),和维度数k(1 <= k <= 5)。
接下来的n行,每行k个整数,代表一个点的坐标。
接下来一个正整数:给定的询问数量t(1 <= t <= 10000)
下面2*t行:
第一行,k个整数:给定点的坐标
第二行:查询最近的m个点(1 <= m <= 10)
所有坐标的绝对值不超过10000。
有多组数据!
【Output】
对于每个询问,输出m+1行:
第一行:"the closest m points are:" m为查询中的m
接下来m行每行代表一个点,按照从近到远排序。
保证方案唯一,下面这种情况不会出现:
2 2
1 1
3 3
1
2 2
1
Input
In the
first line of the text file .there are two non-negative integers n and
K. They denote respectively: the number of points, 1 <= n <=
50000, and the number of Dimensions,1 <= K <= 5. In each of the
following n lines there is written k integers, representing the
coordinates of a point. This followed by a line with one positive
integer t, representing the number of queries,1 <= t <=10000.each
query contains two lines. The k integers in the first line represent the
given point. In the second line, there is one integer m, the number of
closest points you should find,1 <= m <=10. The absolute value of
all the coordinates will not be more than 10000.
There are multiple test cases. Process to end of file.
Output
For each query, output m+1 lines:
The first line saying :”the closest m points are:” where m is the number of the points.
The following m lines representing m points ,in accordance with the order from near to far
It is guaranteed that the answer can only be formed in one ways. The
distances from the given point to all the nearest m+1 points are
different. That means input like this:
2 2
1 1
3 3
1
2 2
1
will not exist.
Sample Input
1 1
1 3
3 4
2
2 3
2
2 3
1
Sample Output
the closest 2 points are:
1 3
3 4
the closest 1 points are:
1 3
Solution
还是K-D Tree模板,不过这个是真正的多维KDT,做的时候把原来的0/1扩展到多维就好了
查询m远的时候开个大根堆,当答案小于堆顶的时候就push进去,然后query内部稍微改一下
因为query的时候lans和rans忘了赋初值调了半天emmm……
Code
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#include<algorithm>
#define N (50000+1000)
#define INF 1e16
using namespace std; struct P
{
long long dis,num;
bool operator < (const P &a) const {return dis<a.dis;}
}po;
long long n,k,D,t,Root,m,ans[N];
priority_queue<P>q; struct Node
{
long long Max[],Min[],d[],lson,rson;
bool operator < (const Node &a) const {return d[D]<a.d[D];}
}p[N],T; struct KDT
{
Node Tree[N];
long long sqr(long long x){return x*x;} void Update(long long now)
{
for (int i=;i<k; ++i)
{
long long ls=Tree[now].lson, rs=Tree[now].rson;
Tree[now].Max[i]=Tree[now].Min[i]=Tree[now].d[i];
if (ls)
{
Tree[now].Max[i]=max(Tree[now].Max[i],Tree[ls].Max[i]);
Tree[now].Min[i]=min(Tree[now].Min[i],Tree[ls].Min[i]);
}
if (rs)
{
Tree[now].Max[i]=max(Tree[now].Max[i],Tree[rs].Max[i]);
Tree[now].Min[i]=min(Tree[now].Min[i],Tree[rs].Min[i]);
}
}
}
long long Build(long long opt,long long l,long long r)
{
if (l>r) return ;
long long mid=(l+r)>>;
D=opt; nth_element(p+l,p+mid,p+r+);
Tree[mid]=p[mid];
Tree[mid].lson=Build((opt+)%k,l,mid-);
Tree[mid].rson=Build((opt+)%k,mid+,r);
Update(mid); return mid;
}
long long Get_min(long long now)
{
long long ans=;
for (int i=; i<k; ++i)
{
if (T.d[i]>Tree[now].Max[i]) ans+=sqr(T.d[i]-Tree[now].Max[i]);
if (T.d[i]<Tree[now].Min[i]) ans+=sqr(Tree[now].Min[i]-T.d[i]);
}
return ans;
}
void Query(int now)
{
long long ls=Tree[now].lson, rs=Tree[now].rson, lans=INF,rans=INF;
if (ls) lans=Get_min(ls);
if (rs) rans=Get_min(rs); long long dist=;
for (int i=; i<k; ++i)
dist+=sqr(Tree[now].d[i]-T.d[i]);
po.dis=dist; po.num=now;
if (dist<q.top().dis)
q.pop(),q.push(po); if (lans<rans)
{
if (lans<q.top().dis) Query(ls);
if (rans<q.top().dis) Query(rs);
}
else
{
if (rans<q.top().dis) Query(rs);
if (lans<q.top().dis) Query(ls);
}
} }KDT; int main()
{
while (scanf("%lld%lld",&n,&k)!=EOF)
{
for (int i=; i<=n;++i)
for (int j=; j<k; ++j)
scanf("%lld",&p[i].d[j]);
Root=KDT.Build(,,n); scanf("%lld",&t);
for (int i=; i<=t; ++i)
{
for (int j=; j<k; ++j)
scanf("%lld",&T.d[j]);
scanf("%lld",&m);
for (int i=; i<=m; ++i)
{
po.dis=INF; po.num=;
q.push(po);
}
KDT.Query(Root); for (int i=; i<=m; ++i)
ans[i]=q.top().num,q.pop();
printf("the closest %lld points are:\n",m);
for (int i=m; i>=; --i)
{
for (int j=; j<k; ++j)
printf("%lld ",p[ans[i]].d[j]);
printf("\n");
}
}
}
}
BZOJ3053:The Closest M Points(K-D Teee)的更多相关文章
- 【kd-tree】bzoj3053 The Closest M Points
同p2626.由于K比较小,所以不必用堆. #include<cstdio> #include<cstring> #include<cmath> #include& ...
- BZOJ3053: The Closest M Points
题解: 我们可以事先在堆里放入插入m个inf然后不断的比较当前值与堆首元素的大小,如果小于的话进入. 估计函数也可以随便写写... query的时候貌似不用保留dir... return 0写在 wh ...
- 【BZOJ 3053】The Closest M Points
KDTree模板,在m维空间中找最近的k个点,用的是欧几里德距离. 理解了好久,昨晚始终不明白那些“估价函数”,后来才知道分情况讨论,≤k还是=k,在当前这一维度距离过线还是不过线,过线则要继续搜索另 ...
- BZOJ 3053 The Closest M Points
[题目分析] 典型的KD-Tree例题,求k维空间中的最近点对,只需要在判断的过程中加上一个优先队列,就可以了. [代码] #include <cstdio> #include <c ...
- 【BZOJ】3053: The Closest M Points(kdtree)
http://www.lydsy.com/JudgeOnline/problem.php?id=3053 本来是1a的QAQ.... 没看到有多组数据啊.....斯巴达!!!!!!!!!!!!!!!! ...
- 【HDOJ】4347 The Closest M Points
居然是KD解. /* 4347 */ #include <iostream> #include <sstream> #include <string> #inclu ...
- bzoj 3053 HDU 4347 : The Closest M Points kd树
bzoj 3053 HDU 4347 : The Closest M Points kd树 题目大意:求k维空间内某点的前k近的点. 就是一般的kd树,根据实测发现,kd树的两种建树方式,即按照方差 ...
- 数据结构(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 ...
- poj:4091:The Closest M Points
poj:4091:The Closest M Points 题目 描写叙述 每到饭点,就又到了一日几度的小L纠结去哪吃饭的时候了.由于有太多太多好吃的地方能够去吃,而小L又比較懒不想走太远,所以小L会 ...
随机推荐
- 常用维护SQL-数据清理
truncate某个库的表数据 show full processlist; select concat('truncate table ',table_schema,'.',table_name,' ...
- Android应用中添加Log4j的示例
[2016-06-30]最新的log4j已经集成在DR_support_lib库中 具体请看: https://coding.net/u/wrcold520/p/DR_support_lib/git/ ...
- google风格
复制一下代码即可: <?xml version="1.0" encoding="UTF-8" standalone="no"?> ...
- jsoup: Java HTML Parser
jsoup Java HTML Parser jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址.HTML文本内容.它提供了一套非常省力的API,可通过DOM,CSS以及类似于j ...
- Linux-Xshell5
Linux-Xshell5 1.下载 2.安装 3.新建会话(连接) 点击新建 需要知道要连接的 IP, 查看命令 ifconfig 配置 名称可以自己命名,主机写要连接的 IP,其他的不能改 输 ...
- 谈谈UI设计的6个实用小技巧
从事UI设计的朋友们,肯定知道我们在做UI设计时,其实是可以通过一些小技巧来帮我们设计的界面更加的漂亮.实用.交互性强,用户体验更好.今天的话,上海艾艺在互联网上面搜寻了几个小技巧.在这里跟大家一起来 ...
- 《X86汇编语言:从实模式到保护模式》读书笔记之引言
有幸结识了<X86汇编语言:从实模式到保护模式>一书.我觉得这本书非常好,语言活泼,通俗易懂,源码丰富,受益匪浅.读罢一遍,意犹未尽.于是打算再读一遍,并把自己的读书所学总结成笔记,一来给 ...
- 记一次MongoDB性能问题
下面文章转载自火丁笔记,原作者描述了一次MongoDB数据迁移过程中遇到的性能问题及其解决方案,中间追查问题的方法和工具值得我们学习.下面是其原文: 最近忙着把一个项目从MySQL迁移到MongoDB ...
- Nginx使用的php-fpm的两种进程管理方式及优化
PS:前段时间配置php-fpm的时候,无意中发现原来它还有两种进程管理方式.与Apache类似,它的进程数也是可以根据设置分为动态和静态的. php-fpm目前主要又两个分支,分别对应于php-5. ...
- 机器学习——GBDT
基础概念 GBDT(Gradient Boosting Decision Tree) 全称梯度提升决策树,是一种迭代的决策树算法.GBDT是集成学习Boosting的家族成员,GBDT中的树是回归树, ...