KD-Tree


  题目大意:K维空间内,与给定点欧几里得距离最近的 m 个点。

  KD树啊……还能怎样啊……然而扩展到k维其实并没多么复杂?除了我已经脑补不出建树过程……不过代码好像变化不大>_>

  然而我WA了。。。为什么呢。。。我也不知道……

  一开始我的Push_up是这么写的:

inline void Push_up(int o){rep(i,k){if (L) t[o].mn[i]=min(t[o].mn[i],t[L].mn[i]),t[o].mx[i]=max(t[o].mx[i],t[L].mx[i]);if (R) t[o].mx[i]=min(t[o].mn[i],t[R].mn[i]),t[o].mx[i]=max(t[o].mx[i],t[R].mx[i]);}
}

  就是如果没有右儿子,就不用它更新了……

  然而我改成zyf的这样:(t[0]初始化一下,mn都置为INF,mx都置为-INF)

inline void Push_up(int o){rep(i,k){t[o].mn[i]=min(t[o].mn[i],min(t[L].mn[i],t[R].mn[i]));t[o].mx[i]=max(t[o].mx[i],max(t[L].mx[i],t[R].mx[i]));}
}

  就过了……………… 

P.S.多组数据的题目,KD-Tree一定要记得清空 l 和 r ……要不然叶子节点会有一些奇怪的问题……

获得称号:

  1 /**************************************************************
  2     Problem: 3053
  3     User: Tunix
  4     Language: C++
  5     Result: Accepted
  6     Time:1364 ms
  7     Memory:9088 kb
  8 ****************************************************************/
  9
 10 //BZOJ 3053
 11 #include<queue>
 12 #include<cmath>
 13 #include<cstdio>
 14 #include<cstring>
 15 #include<cstdlib>
 16 #include<iostream>
 17 #include<algorithm>
 18 #define rep(i,n) for(int i=0;i<n;++i)
 19 #define F(i,j,n) for(int i=j;i<=n;++i)
 20 #define D(i,j,n) for(int i=j;i>=n;--i)
 21 #define pb push_back
 22 #define sqr(x) ((x)*(x))
 23 using namespace std;
 24 typedef long long LL;
 25 inline int getint(){
 26     int r=1,v=0; char ch=getchar();
 27     for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1;
 28     for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch;
 29     return r*v;
 30 }
 31 const int N=100010,INF=1e9;
 32 /*******************template********************/
 33
 34 int n,k,D,root,ans[15];
 35 struct node{
 36     int d[6],mn[6],mx[6],l,r;
 37     int& operator [] (int x){return d[x];}
 38     void read(){rep(i,k) d[i]=getint();}
 39 }t[N],tmp;
 40 bool operator < (node a,node b){return a[D]<b[D];}
 41 #define L t[o].l
 42 #define R t[o].r
 43 #define mid (l+r>>1)
 44 inline void Push_up(int o){
 45     rep(i,k){
 46         t[o].mn[i]=min(t[o].mn[i],min(t[L].mn[i],t[R].mn[i]));
 47         t[o].mx[i]=max(t[o].mx[i],max(t[L].mx[i],t[R].mx[i]));
 48     }
 49 }
 50 int build(int l,int r,int dir){
 51     D=dir;
 52     nth_element(t+l,t+mid,t+r+1);
 53     rep(i,k) t[mid].mn[i]=t[mid].mx[i]=t[mid][i];
 54     t[mid].l=l<mid ? build(l,mid-1,(dir+1)%k) : 0;
 55     t[mid].r=mid<r ? build(mid+1,r,(dir+1)%k) : 0;
 56     Push_up(mid);
 57     return mid;
 58 }
 59 inline int getdis(int o){
 60     if (!o) return INF;
 61     int ans=0;
 62     rep(i,k) if (tmp[i]<t[o].mn[i]) ans+=sqr(t[o].mn[i]-tmp[i]);
 63     rep(i,k) if (tmp[i]>t[o].mx[i]) ans+=sqr(tmp[i]-t[o].mx[i]);
 64     return ans;
 65 }
 66 inline int dis(node a,node b){
 67     int ans=0;
 68     rep(i,k) ans+=sqr(a[i]-b[i]);
 69     return ans;
 70 }
 71 typedef pair<int,int> pii;
 72 priority_queue<pii>Q;
 73 #define mp make_pair
 74 #define X first
 75 #define Y second
 76 void query(int o){
 77     int dl=getdis(L),dr=getdis(R),d0=dis(t[o],tmp);
 78     if (d0<Q.top().X){Q.pop(); Q.push(mp(d0,o));}
 79     if (dl<dr){
 80         if (dl<Q.top().X) query(L);
 81         if (dr<Q.top().X) query(R);
 82     }else{
 83         if (dr<Q.top().X) query(R);
 84         if (dl<Q.top().X) query(L);
 85     }
 86 }
 87 int main(){
 88 #ifndef ONLINE_JUDGE
 89     freopen("3053.in","r",stdin);
 90     freopen("3053.out","w",stdout);
 91 #endif
 92     rep(i,5) t[0].mn[i]=INF,t[0].mx[i]=-INF;
 93     while(scanf("%d%d",&n,&k)!=EOF){
 94         F(i,1,n) rep(j,k) t[i][j]=getint();
 95         root=build(1,n,0);
 96         int T=getint();
 97         while(T--){
 98             rep(j,k) tmp[j]=getint();
 99             n=getint();
100             printf("the closest %d points are:\n",n);
101             F(i,1,n) Q.push(mp(INF,0));
102             query(root);
103             D(i,n,1) ans[i]=Q.top().Y,Q.pop();
104             F(i,1,n) rep(j,k)
105                 printf("%d%c",t[ans[i]][j],j!=k-1?' ':'\n');
106         }
107     }
108     return 0;
109 }

View Code

3053: The Closest M Points

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 383  Solved: 147
[Submit][Status][Discuss]

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

3 2
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

HINT

Source

k-d tree

[Submit][Status][Discuss]

转载于:https://www.cnblogs.com/Tunix/p/4515464.html

【BZOJ】【3053】The Closest M Points相关推荐

  1. 【BZOJ—2957楼房重建】【连载:请在T台上微笑】

    长久没有发博文了...对对对, 所以最近就趁着暑假多发发吧 颓废是革命的本钱: 推荐一个我喜欢的新连载漫画吧[请在T台上微笑] BZOJ 2957 [楼房重建] Description 小A的楼房外有 ...

  2. 【bzoj 十连测】[noip2016十连测第三场]Problem C: 序列(静态主席树)

    Problem C: [noip2016十连测第三场]序列 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 78  Solved: 32 [Submi ...

  3. 【bzoj 1806/CS 1801】矿工配餐 IOI2007(五维DP+滚动数组)

    楼下是传送门: http://www.lydsy.com/JudgeOnline/problem.php?id=1806 Description 现有两个煤矿,每个煤矿都雇用一组矿工.采煤工作很辛苦, ...

  4. BZOJ 2151 种树(可反悔贪心,链表)【BZOJ千题计划】就图一乐

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目链接 https://hydro.ac/d/bzoj/p/2151 是 hydro 的 BZOJ ...

  5. BZOJ 2150. 部落战争(最小路径覆盖问题)【BZOJ千题计划】

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 刷题就图一乐 题目链接 https://hydro.ac/d/bzoj/p/2150 是 hydro ...

  6. 【bzoj 2460 [BeiJing2011]元素】

    题意:  相传,在远古时期,位于西方大陆的 Magic Land 上,人们已经掌握了用魔 法矿石炼制法杖的技术.那时人们就认识到,一个法杖的法力取决于使用的矿石. 一般地,矿石越多则法力越强,但物极必 ...

  7. 【BZOJ 3926】【ZJOI 2015】 诸神眷顾的幻想乡

    [BZOJ 3926/ZJOI 2015] 诸神眷顾的幻想乡 [广义SA/广义SAM] 没想到陈立杰居然玩旧作- 题意: \;\;\;\;啊?~幻想乡?~一个树状太阳花田上每个点都有人穿着 c c种颜 ...

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

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

  9. 【BZOJ】【2154】Crash的数字表格

    莫比乌斯反演 PoPoQQQ讲义第4题 题解:http://www.cnblogs.com/jianglangcaijin/archive/2013/11/27/3446169.html 感觉两次sq ...

  10. 【BZOJ】【1038】【ZJOI2008】瞭望塔

    计算几何/半平面交 说是半平面交,实际上只是维护了个下凸壳而已--同1007水平可见直线 对于每条线段,能看到这条线段的点都在这条线段的"上方",那么对所有n-1条线段求一个可视区 ...

最新文章

  1. 12.前K个高频元素---使用优先队列和哈希表解决
  2. IDC dump 内存
  3. html + css实现油画商场页面
  4. 技术实践丨React Native 项目 Web 端同构
  5. ★☆★cf D. Petya and Array
  6. Aspose.Words for .NET
  7. 在应用中集成科大讯飞的语音识别技术
  8. Java开发中,接口参数校验
  9. 西门子PLC入门-PLC介绍
  10. sublime Mac版怎么安装? Mac下载安装sublime的教程
  11. 【历史上的今天】6 月 30 日:冯·诺依曼发表第一份草案;九十年代末的半导体大战;CBS 收购 CNET
  12. 化繁为简,微软 Desktop Flow(“RPA”)正式在华商用!
  13. 职场常用的办公软件,操作很方便
  14. UiPath是做什么的
  15. crh寄存器_STM32的寄存器控制SDA_IN()/SDA_OUT()
  16. 1860-zbj的电梯间
  17. hbase 二进制数据写入_linux 写入二进制文件内容
  18. Oracle特殊字符,转义字符的处理
  19. c语言版本常用,C语言常用词汇表最新版本.doc
  20. vb.net——通过邮箱动态发送验证码实现完美注册

热门文章

  1. php解压7z,linux解压7z文件命令
  2. 电脑局域网所有IP及对应MAC地址查询
  3. 基于Halcon的高精度圆拟合算法思路
  4. UE4 通过蓝图实现蓝图接口
  5. 青蛙跳Java程序,青蛙跳台阶(java)
  6. python如何去除文本标点符号_python中如何去除标点符号
  7. jzoj3457. 【NOIP2013模拟联考3】沙耶的玩偶
  8. 帆软报表多数据集关联合并操作
  9. Gin源码之gin.Context结构体及其方法
  10. 波士顿大学 计算机专业,波士顿大学本科计算机专业课程设置是怎样的?