Processing math: 100%

k-D Tree学习笔记

某人奶了一口省选会考,于是认真学了学。

形态

k-D Tree 是一棵二叉搜索树,每个结点都对应 k 维空间中的一个点,每个子树中的点都在且都仅在一个 k 维超长方体内。

构建

假设已知 k 维空间中的 n 个互不相同的点的坐标,要将其构建为一棵 k-D Tree。

  1. 当前超长方体中只有一个点时直接返回该点。
  2. 选择一个维度与该维度上的一个切割点,将当前超长方体按这个维度及这个切割点分为两个超长方体。
  3. 将选择的切割点作为该子树的根,递归处理分出的两个超长方体。

容易发现,对于步骤 2,每次切割点选为该维度上的中位数,树高可以在 O(logn)

如何寻找中位数?可以使用类似快速排序的方法,并且每次只递归包含中位数的一侧,对于 n 个元素的序列期望时间复杂度即为 O(n)。(可用algorithm库中的nth_element()实现)

每次选什么维度来割?理论上应当每次选方差最大的维度割常数应当最小,然而算法竞赛中较常用且方便的写法是直接轮流按每一维割

插入与删除

点集可变,可以利用替罪羊树不平衡重构的方法把树高稳定在 O(logn)

然而实验证明定期整树重构通常来说常数更小。

查询超长方体

若该结点完全被包含于超长方体内,或完全与其无交可直接返回。

否则应递归两边。

可以证明复杂度最坏为 O(n11k)

习题

[Luogu 4148]简单题

初值全为 0 的 n×n 二维矩阵上, q 个操作:

  1. 单点修改。
  2. 矩形查询和。

强制在线,内存限制20M,答案及过程量均int范围内。n5×105,q2×105


空间卡树套树,强制在线卡 CDQ 分治,于是只能 KDT。

不要不平衡重构,定期重构常数更小。

写写写,写就完事了。

参考资料

OI Wiki

0 comments
Anonymous
Markdown is supported

Be the first guy leaving a comment!