初步认识\(K-D\) \(Tree\)

\(K-D\) \(Tree\)是一种基于空间分割的二叉树形数据结构,一般用于高维信息检索。因为\(OI\)中很多问题都能转化为高维信息检索,所以\(K-D\) \(Tree\)的用途十分广泛。

\(K-D\) \(Tree\)树高严格为\(logn\)每一个结点都代表着一个高维信息点。每一棵子树表示的范围是该子树内所有点的\(k\)维正交包围盒,左右子树代表的范围不相交。

建树

\(K-D\) \(Tree\)一般采用中位数循环切割的方式建树。假设当前结点是以第\(x\)维中位数分割成两棵子树的,那么当前节点的儿子结点就应该用第\((x+1)mod\) \(k\)维中位数来切割。以\(k=2\)为例:

总之就是切完\(x\)就切\(y\)啦。求中位数可以用\(\rm std::nth\)_\(\rm element()\),复杂度\(O(n)\),会把中位数放到序列中间来。

建树总时间复杂度:\(T(n)=2T(n/2)+O(n)=O(nlogn)\)

插入

就像二叉查找树一样一直搜索到底,作为叶子插入。但是数据不随机的时候有可能会使树退化成链,所以需要用到替罪羊树重构的方式保持平衡。均摊\(O(log^2n)\)。由于保持平衡的代价较大,所以不强制在线的时候,应该把插入换成激活,也就是先把这个点扔里面,但是处于未激活的状态,点上的信息不进入统计范围。激活之后就算是一个实实在在存在的结点了。

删除

不能真的从树里删掉某个点,因为那样会改变树的结构。用激活的反操作把它标记掉,如果要重构树的时候再清掉。

最近点查询

我们可以用\(O(1)\)的时间求出某个点到左右子树正交包围盒的最短距离,先去较小的那个子树里求答案,再来访问较大的子树。用最优性剪纸,如果当前最短距离比已经求出来的答案还大的话那就不访问这个子树了。在数据随机的情况下期望复杂度为\(O(logn)\)

正交范围查询

从根开始查询,如果当前子树与查询范围没有交集则直接退出,被完全包含就统计信息之后直接退出,否则递归访问左右子树。\(k\)维的\(k-d\) \(tree\)正交范围查询的复杂度是\(O(n^{\frac{k-1}{k}})\),\(k=2\)为例:

假设查询范围只有上边界和右边界,两层孩子一共\(4\)棵子树,每棵\(\frac{n}{4}\)个点。这\(4\)棵子树中有一棵完全被包含=\(O(1)\),\(2\)棵子树只有一个边界=\(2F(\frac{n}{4})\),还有一棵与原问题一致=\(T(\frac{n}{4})\)。

对于只有一个边界的问题来说,该边界只会与两棵子树相交,所以\(F(n)=2F(\frac{n}{4})+O(1)=O(\sqrt{n})\)

所以\(2\)维\(k-d\) \(tree\)的正交范围查询复杂度为\(T(n)=T(\frac{n}{4})+O(\sqrt{n})=O(\sqrt{n})\)

如果遇到\(TLE\),那么请第一时间来检查子树正交包围盒范围是否可能出错。

有没有可能通过空儿子得到错误的范围。最好一开始就把\(0\)结点的范围设成极值。

\(K-D\) \(Tree\)与传统树套树的比较

空间复杂度为\(O(n)\),不容易被卡空间。

结构简单并且支持复杂的操作。

便于剪枝,因为寻址快,效率一般更好。

浅谈K-D Tree的更多相关文章

  1. 浅谈k短路算法

    An Old but Classic Problem 给定一个$n$个点,$m$条边的带正权有向图.给定$s$和$t$,询问$s$到$t$的所有权和为正路径中,第$k$短的长度. Notice 定义两 ...

  2. 浅谈算法和数据结构: 七 二叉查找树 八 平衡查找树之2-3树 九 平衡查找树之红黑树 十 平衡查找树之B树

    http://www.cnblogs.com/yangecnu/p/Introduce-Binary-Search-Tree.html 前文介绍了符号表的两种实现,无序链表和有序数组,无序链表在插入的 ...

  3. 浅谈分词算法(4)基于字的分词方法(CRF)

    目录 前言 目录 条件随机场(conditional random field CRF) 核心点 线性链条件随机场 简化形式 CRF分词 CRF VS HMM 代码实现 训练代码 实验结果 参考文献 ...

  4. 浅谈分词算法(3)基于字的分词方法(HMM)

    目录 前言 目录 隐马尔可夫模型(Hidden Markov Model,HMM) HMM分词 两个假设 Viterbi算法 代码实现 实现效果 完整代码 参考文献 前言 在浅谈分词算法(1)分词中的 ...

  5. cdq分治浅谈

    $cdq$分治浅谈 1.分治思想 分治实际上是一种思想,这种思想就是将一个大问题划分成为一些小问题,并且这些小问题与这个大问题在某中意义上是等价的. 2.普通分治与$cdq$分治的区别 普通分治与$c ...

  6. (转)浅谈trie树

    浅谈Trie树(字典树)         Trie树(字典树) 一.引入 字典是干啥的?查找字的. 字典树自然也是起查找作用的.查找的是啥?单词. 看以下几个题: 1.给出n个单词和m个询问,每次询问 ...

  7. 浅谈分词算法基于字的分词方法(HMM)

    前言 在浅谈分词算法(1)分词中的基本问题我们讨论过基于词典的分词和基于字的分词两大类,在浅谈分词算法(2)基于词典的分词方法文中我们利用n-gram实现了基于词典的分词方法.在(1)中,我们也讨论了 ...

  8. 浅谈 Java集合

    Java 集合 集合是对象的容器,定义了多个对象进行操作的常用方法,可实现数组的功能. Java集合类库所处位置:java.util.*. 与现代的数据结构类库的常见做法一样,Java集合类库也将接口 ...

  9. 浅谈Hybrid技术的设计与实现

    前言 浅谈Hybrid技术的设计与实现 浅谈Hybrid技术的设计与实现第二弹 浅谈Hybrid技术的设计与实现第三弹——落地篇 随着移动浪潮的兴起,各种APP层出不穷,极速的业务扩展提升了团队对开发 ...

  10. Spring缓存框架原理浅谈

    运维在上线,无聊写博客.最近看了下Spring的缓存框架,这里写一下 1.Spring 缓存框架 原理浅谈 2.Spring 缓存框架 注解使用说明 3.Spring 缓存配置 + Ehcache(默 ...

随机推荐

  1. Android L 64位兼容32 应用程序的认识

    http://blog.csdn.net/louyong0571/article/details/44223481 关于Android L 64位系统兼容32位应用的实现的简单分析. Android ...

  2. OpenStack虚拟机创建过程中镜像格式的的变化过程

    Glance用来作为独立的大规模镜像查找服务,当它与Nova和Swift配合使用时,就为OpenStack提供了虚拟机镜像的查找服务,像所有的OpenStack项目一样,遵循以下设计思想: 基于组件的 ...

  3. PHP 最大化资源配置 Resource Limits 错误两则

    报错信息1:PHP Fatal error: Allowed memory size of 25165824 bytes exhausted (tried to allocate 67108888 b ...

  4. Ubuntu登陆不进去(已解决)【转】

    本文转载自:https://blog.csdn.net/u010925447/article/details/72236387 Ubuntu一直在登陆界面循环:登陆密码是正确的,但是登陆后自动退回登陆 ...

  5. nginx常见面试题1

    Nginx是网页服务器运维人员不可能绕开的一个弯,剩下几个比较高危的面试范围是:linux基础.网络知识基础.python,或许还会有zabbix等监控工具.这里先说nginx,后面几个肯定也会写. ...

  6. 解决noSession问题

    1.问题描述:对于根据id查询时,在dao通过load方式查询对象时,加载页面会报 noSession异常. 严重: Servlet.service() for servlet [springDisp ...

  7. Java C++ 比较 – 虚函数、抽象函数、抽象类、接口

    [转自]原文 Java – 虚函数.抽象函数.抽象类.接口 1. Java虚函数 虚函数的存在是为了多态. C++中普通成员函数加上virtual关键字就成为虚函数 Java中其实没有虚函数的概念,它 ...

  8. Qt QTreeWidget节点的添加+双击响应+删除详解

    转自: http://www.cnblogs.com/Romi/archive/2012/08/08/2628163.html 承接该文http://www.cnblogs.com/Romi/arch ...

  9. 3Sum,4Sum问题

    //三数和为0的问题.要求去重,并且输出数字有序.public List<List<Integer>> threeSum(int[] nums) { Arrays.sort(n ...

  10. lightoj1422 区间dp

    对于这一题想了很久真的是一点头绪也没有,还有组数明明是200,数据范围100,O(n^3)的复杂度居然不会爆掉(可能是因为一直在想怎么用O(n^2)的复杂度做这题 做法是先预处理dp,对于dp[i][ ...