核心思想

是一种分割 \(k\) 维数据空间的数据结构

一维情况下就是平衡树,以 \(key\) 为标准判断插入左儿子还是右儿子

\(kdtree\) 就是平衡树在多维空间的扩展

因为有多维,我们按不同维度交错作为关键字进行插入与查询

如:第一层按照第一维排序,第二层按照第二维排序,第 \(k\) 层按照第 \(k\) 维排序

每一层取该维的中位数,把空间中的点分割开来,分别作为当前点的左右儿子,直到该层只有一个点停止

实现与运用

在 \(OI\) 中,运用最多的是二维的情况,一般当作优秀的暴力来用

如查询离某个点最远/近的点,插入一个点........

首先可以定义一个类,方便每一层排序和分割使用,定义一个重载运算符 \([x]\) 就可以方便的以第 \(x\) 维排序了

struct data{
int a[K],mn[K],mx[K],l,r;
inline int& operator [](int x){return a[x];}
}t[N];
inline bool operator <(data p,data q){return p[D]<q[D];}

\(build\) 操作

inline int build(int l,int r,int k){
D=k;
int mid=(l+r)>>1,o=mid;
nth_element(t+l,t+mid,t+r+1);
for(int i=0;i<2;i++)t[o].mn[i]=t[o].mx[i]=t[o][i];
if(l<mid)t[o].l=build(l,mid-1,k^1);
if(r>mid)t[o].r=build(mid+1,r,k^1);
return upd(o),o;
}

用到了 \(STL\) \(nth\_element\), 这个系统函数支持查找第 \(k\) 大数,并实现分割的效果

具体来说,\(nth\_element(a+1,a+mid,t+r+1)\) 后,会把 \(a\) 数组中第 \(mid\) 大的数放到第 \(mid\) 位置,并把小于 \(mid\) 的放到 \(mid\) 这个位置之前,大于的放到后面(但左右内部都是无序的),完美的达到了分割的效果

\(query\) 操作:

拿查询离某个点最远的点举例

我们需要定义一个估价函数:

例子中也就是不管合法性的情况下,离这个点可能的距离的最大值,把两维分开考虑相加即可

一半来说是维护一个最小矩形,使得这个节点子树内的节点都可以被包含,查询时与这个矩形有交才往下递归

一次查询的复杂度期望是 \(O(n^{1-1/k}+m)\) m---每次要搜索的最近点个数

inline int cmax(int o){
if(!o)return 0;
int ret=0;
for(int i=0;i<2;i++)
ret+=max(abs(t[o].mx[i]-t[I][i]),abs(t[o].mn[i]-t[I][i]));
return ret;
}

求出两个儿子的估价函数之后,先递归较优的一边,判断是否可能比答案更优,不可能优则不递归

inline void qmax(int o){
int dl=cmax(t[o].l),dr=cmax(t[o].r),dc=dis(o);
tmax=max(tmax,dc);
if(dl>dr){
if(dl>tmax)qmax(t[o].l);
if(dr>tmax)qmax(t[o].r);
}
else{
if(dr>tmax)qmax(t[o].r);
if(dl>tmax)qmax(t[o].l);
}
}

\(insert\) 操作

与平衡树类似,判断与当前节点大小关系判断左右走向,可以用定期重构稳定复杂度,数据范围较大时,不重构效果更好

inline int ins(int o,int k){
if(!o)return cnt;
if(e[k]>t[o][k])t[o].r=ins(t[o].r,k^1);
else t[o].l=ins(t[o].l,k^1);
return upd(o),o;
}

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. K-D Tree题目泛做(CXJ第二轮)

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

  6. k-d Tree in TripAdvisor

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

  7. k-d tree算法

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

  8. k-d tree模板练习

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

  9. [模板] K-D Tree

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

  10. BZOJ3489 A simple rmq problem K-D Tree

    传送门 什么可持久化树套树才不会写呢,K-D Tree大法吼啊 对于第\(i\)个数,设其前面最后的与它值相同的位置为\(pre_i\),其后面最前的与它值相同的位置为\(aft_i\),那么对于一个 ...

随机推荐

  1. 百万数据测试 Entity Framework 到底有多慢

    测试环境 硬件:阿里云乞丐配置 操作系统:Centos 7 CPU: 1核 内存:1 GB (I/O优化) 网络:1Mbps(峰值) 软件 .net core 2.0 ZKEACMS For .net ...

  2. asp.net(mvc) 框架

    1.NFine mvc+ef 2.Grove orm架构 3.NHibernate orm 4.NBear 5.petshop 6.Membership 7.Brnshop 网上商城 8.cms快速开 ...

  3. 爬虫开发11.scrapy框架之CrawlSpider操作

    提问:如果想要通过爬虫程序去爬取”糗百“全站数据新闻数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模块递归回调parse方法). 方法二:基 ...

  4. JSR133规范学习

    最近在看多线程相关的东西,通过阅读JSR133的faq来加深自己对多线程的理解,里面大部分的内容比较简单(越到后面越难),但是有的部分比较难以理解还没有完全弄懂,所以这里只记录了一下比较简单的阅读笔记 ...

  5. 基于Java软引用机制最大使用JVM堆内存并杜绝OutOfMemory

    题记:说好的坚持一周两篇文章在无数琐事和自己的懒惰下没有做好,在此表达一下对自己的不满并对有严格执行力的人深表敬意!!!! -------------------------------------- ...

  6. UDF-Java提取身份证内信息

    1.使用方法 #获取省份ID create temporary function getProvIdByCardIdUDF as 'com.st.PersonInfoByCardIdUDF.getPr ...

  7. leetcode-788-Rotated Digits(使用vector替代if else的逐个判断)

    题目描述: X is a good number if after rotating each digit individually by 180 degrees, we get a valid nu ...

  8. html5兼容问题

    1.html5对于ie9一下的版本不支持,所以我们可以添加(你可以下载至本地): <!--[if lt IE 9]> <script src="http://cdn.sta ...

  9. php图像处理函数image_type_to_extension、image_type_to_mime_type 的区别

    php中获得图像类型的两个函数image_type_to_extension.image_type_to_mime_type,做图像处理的时候一直不清楚这俩个函数有什么区别,今天特意查了一下,有了一些 ...

  10. Linux串口驱动程序设计

    1. 在Linux系统中,终端是一类字符型设备,它包括多种类型,通常使用tty来简称各种类型的终端设备. (1)串口终端(/dev/ttyS*):串口终端是使用计算机串口连接的终端设备.Linux把每 ...