还记得青岛的时候和蕾姐讨论了近三个小时也不知道这是什么东西 后来发现是kdtree 于是拖到寒假才补这个算法

写完几道模板题发现多维的kdtree查找最近也是很简单的拓展 于是很快1A了这道题 它真的只是模板 但确实是青岛的金牌题

如果如果如果如果 那么多如果 可惜没如果...

我花了很长时间去学了一个以后可能再也不会考到的算法

就当是对过去的一些..补偿吧..?

和普通的kdtree相比加了一个价钱的限制条件和一个输出最前面的id的限制条件

先建好树 然后直接查询 不用插入

对每个点判断dis的时候 如果价钱高于预期 距离就变为INF 低于预期就没有影响

如果dl 或者 dr 和当前最近的dis 相等 就继续ask以得到更小的id

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<math.h>
#include<queue>
#include<string>
using namespace std;
#define L long long
const L maxn = 200050 ;
const L INF = 999999999999999999 ;
/**
做一个三维的kdtree 进行最近距离的查找 同时记录最近的ans和最近的编号 随时进行对比
getdis函数 如果小于等于z 距离加上0 否则加上INF
*/ L n , m , cmp_d , root ;
struct node {
L l , r ;
L d[3] , Max[3] , Min[3] ;
L c ;
L id ;
}a[maxn];
bool cmp(node a , node b ){
return a.d[cmp_d] < b.d[cmp_d] ;
}
void up(L p , L k ) {
for(L i = 0; i < 3 ; i ++ ){
a[p].Min[i] = min(a[p].Min[i] , a[k].Min[i]) ;
a[p].Max[i] = max(a[p].Max[i] , a[k].Max[i]) ;
}
}
L build(L l, L r , L D) {
cmp_d = D ;
L mid = (l+r)/2 ;
nth_element(a+1+l,a+1+mid,a+1+r,cmp) ;
for(L i = 0 ;i < 3 ; i ++) a[mid].Min[i] = a[mid].Max[i] = a[mid].d[i] ;
if(l != mid) a[mid].l = build(l,mid-1,(D+1)%3) ; else a[mid].l = 0 ;
if(r != mid) a[mid].r = build(mid+1,r,(D+1)%3) ; else a[mid].r = 0 ;
if(a[mid].r)up(mid,a[mid].r);
if(a[mid].l)up(mid,a[mid].l);
return mid ;
}
L x,y,z;
L jl , ans ;
L getdis(L p) {
L res = 0 ;
if(z < a[p].Min[2]) return INF + 1 ;
if(x > a[p].Max[0]) res += (x - a[p].Max[0]) * (x - a[p].Max[0]) ;
if(x < a[p].Min[0]) res += (a[p].Min[0] - x) * (a[p].Min[0] - x) ;
if(y > a[p].Max[1]) res += (y - a[p].Max[1]) * (y - a[p].Max[1]) ;
if(y < a[p].Min[1]) res += (a[p].Min[1] - y) * (a[p].Min[1] - y) ;
return res ;
}
void ask(L p) {
L d0 = 0 ;
L dl , dr ;
if(a[p].d[2] > z)d0 += INF ;
if(d0 == 0) {
d0 += ((a[p].d[0]) - x) * ((a[p].d[0]) - x ) + ((a[p].d[1]) - y) * ((a[p].d[1]) - y ) ;
if(d0 < jl){
ans = p ;
jl = d0 ;
}
else if(d0 == jl) {
if(a[p].id < a[ans].id) {
ans = p;
}
}
}
if(a[p].l)dl = getdis(a[p].l) ; else dl = INF + 1 ;
if(a[p].r)dr = getdis(a[p].r) ; else dr = INF + 1 ;
if(dl < dr ) {
if(dl <= jl) ask(a[p].l) ;
if(dr <= jl) ask(a[p].r) ;
}
else {
if(dr <= jl) ask(a[p].r) ;
if(dl <= jl) ask(a[p].l) ;
}
}
int main(){
L t;
scanf("%lld",&t);
while(t-- ) {
scanf("%lld%lld",&n,&m) ;
for(L i=1;i<=n;i++){
for(L k=0;k<3;k++)scanf("%lld",&a[i].d[k]) ;
a[i].l = a[i].r = 0 ;
a[i].id = i ;
}
root = build(1,n,0);
for(L i=1;i<=m;i++){
scanf("%lld%lld%lld",&x,&y,&z) ;
jl = INF ;
ans = -1 ;
ask(root);
printf("%lld %lld %lld\n",a[ans].d[0],a[ans].d[1],a[ans].d[2]) ;
}
}
}

(去看了乘风破浪 感觉粉赵丽颖了QAQ

HDU 5992 kd-tree的更多相关文章

  1. AOJ DSL_2_C Range Search (kD Tree)

    Range Search (kD Tree) The range search problem consists of a set of attributed records S to determi ...

  2. k-d tree 学习笔记

    以下是一些奇怪的链接有兴趣的可以看看: https://blog.sengxian.com/algorithms/k-dimensional-tree http://zgjkt.blog.uoj.ac ...

  3. 【BZOJ-2648&2716】SJY摆棋子&天使玩偶 KD Tree

    2648: SJY摆棋子 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2459  Solved: 834[Submit][Status][Discu ...

  4. K-D Tree

    这篇随笔是对Wikipedia上k-d tree词条的摘录, 我认为解释得相当生动详细, 是一篇不可多得的好文. Overview A \(k\)-d tree (short for \(k\)-di ...

  5. HDU 5513 Efficient Tree

    HDU 5513 Efficient Tree 题意 给一个\(N \times M(N \le 800, M \le 7)\)矩形. 已知每个点\((i-1, j)\)和\((i,j-1)\)连边的 ...

  6. K-D Tree题目泛做(CXJ第二轮)

    题目1: BZOJ 2716 题目大意:给出N个二维平面上的点,M个操作,分为插入一个新点和询问到一个点最近点的Manhatan距离是多少. 算法讨论: K-D Tree 裸题,有插入操作. #inc ...

  7. k-d Tree in TripAdvisor

    Today, TripAdvisor held a tech talk in Columbia University. The topic is about k-d Tree implemented ...

  8. k-d tree算法

    k-d树(k-dimensional树的简称),是一种分割k维数据空间的数据结构.主要应用于多维空间关键数据的搜索(如:范围搜索和最近邻搜索). 应用背景 SIFT算法中做特征点匹配的时候就会利用到k ...

  9. k-d tree模板练习

    1. [BZOJ]1941: [Sdoi2010]Hide and Seek 题目大意:给出n个二维平面上的点,一个点的权值是它到其他点的最长距离减最短距离,距离为曼哈顿距离,求最小权值.(n< ...

  10. [模板] K-D Tree

    K-D Tree K-D Tree可以看作二叉搜索树的高维推广, 它的第 \(k\) 层以所有点的第 \(k\) 维作为关键字对点做出划分. 为了保证划分均匀, 可以以第 \(k\) 维排名在中间的节 ...

随机推荐

  1. CodeIgniter框架——源码分析之CodeIgniter.php

    CodeIgniter.php可以说是CI的核心,大部分MVC的流程都是在这个文件夹中处理的,其中加载了很多外部文件,完成CI的一次完整流程. 首先是定义了CI的版本(此处为CI 2.2.0),接下来 ...

  2. Win7系统安装 MySQL 8.0.11

    1. 下载 MySQL 8.0.11 版本 下载地址: https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.11-winx64.zip 2. 下载 ...

  3. 贝叶斯网(2)Netica:从数据中学习CPT

    1. 离散节点 在官方Tutorial中是有详细的案例的,就是B篇3.3节,你可以动手把天气预报这个实现一下: http://www.norsys.com/tutorials/netica/secB/ ...

  4. 我的Android进阶之旅------>Android中查看应用签名信息

    一.查看自己的证书签名信息 如上一篇文章<我的Android进阶之旅------>Android中制作和查看自定义的Debug版本Android签名证书>地址:http://blog ...

  5. 我的Android进阶之旅------>Android使用cmd窗口进行adb logcat时出现中文乱码问题的解决办法

    今天用CMD命令进行adb logcat时显示一堆的乱码,乱码如下: C:\Users\Administrator>adb logcat -s logcat --------- beginnin ...

  6. 单例 与 static

    单例的构造器是private的,不能直接用new 创建对象.static虽然可以随时使用,但是还是有被重新创建的可能. 举个例子,你希望任何时候有一个class A的实例就可以了class B {  ...

  7. 0405-服务注册与发现-客户端负载均衡-Ribbon 同Eureka使用,Ribbon脱离Eureka使用

    一.Ribbon 同Eureka使用,注意事项 前几节一同使用,注意事项: 如果没有其他区域数据源,则根据客户端配置进行猜测(与实例配置相反).能够获取eureka.client.availabili ...

  8. 001-Eclipse、idea集成javap查看字节码、javap说明

    一.概述 分析java语言特性的一个好帮手是使用javap工具查看java编译后的字节码,如何在eclipse中配置javap工具快速查看java字节码. 二.Eclipse集成javap查看字节码 ...

  9. 剑指offer 面试53题

    面试53题: 题目:统计一个数字在排序数组中出现的次数. 思路:二分查找法,分别找到此数字在排序数组中第一次和最后一次出现的位置,然后次数等于两个位置之差加1. 时间复杂度:O(log n) 解题代码 ...

  10. C#加快Bitmap的访问速度

    在对Bitmap图片操作的时候,有时需要用到获取或设置像素颜色方法:GetPixel 和 SetPixel, 如果直接对这两个方法进行操作的话速度很慢,这里我们可以通过把数据提取出来操作,然后操作完在 ...