KDT学习笔记

KDT处理的一些问题:给你一个 \(k\) 维空间,\(n\) 个点,每次查询一个超矩形,求这个超矩形里面包含的点的信息,以下默认 \(k=2\)

建树

重复以下流程:

  • 轮流选择 \(k\) 维作为划分依据。
  • 选择第 \(k\) 维里的中位数作为根。

求中位数的过程是 \(O(n)\) 的,每次划分数据规模都会 \(/2\),所以建树总时间复杂度为 \(O(n\log n)\)

查询

KDT的重点。

如果查询的超矩形和当前划分出的超矩形无交,那么直接返回。

如果查询的超矩形包含当前划分出的超矩形,直接返回矩形信息。

如果查询的超矩形部分包含当前划分出的超矩形,我们考虑超矩形的一条边,这条边最多只能穿过当前划分出的超矩形的两个孙子节点,另外的两个要么被包含,要么不交。

根据这个可以写出:\(T(n)=2(\frac T4)+O(1)\) ,总时间复杂度就是 \(O(\sqrt n)\)

插入

我们发现KDT查询的时间复杂度依赖于严格 \(\log n\) 的树高,这使得我们不能使用类似treap的期望 \(O(\log n)\) 或者类 \(O(\log n)\) 去做。

我们有两个方法维护。

1.定期重构

由于建树是 \(O(n\log n)\) 的,我们可以每 \(B\) 次插入重构一遍,查询复杂度 \(O(\sqrt n +B)\) ,插入复杂度 \(O(\frac{n\log n} B)\)

\(n,q\) 同阶时 \(B\)\(\sqrt{n\log n}\) 最优,此时查询插入时间复杂度均为 \(O(\sqrt{n\log n})\)

2.二进制分组

KDT合并的时间复杂度为 \(O(n\log n)\) ,考虑维护 \(2\) 的整数次幂棵KDT,若出现两个相同大小的KDT就将其合并,插入的总时间复杂度为 \(O(n\log^2 n)\) 的,查询的时间复杂度\(O(∑_{𝑖≥0}\sqrt{\frac n{2^i}}) =O(\sqrt n)\)

posted @ 2026-01-16 15:47  Sgt_Dante  阅读(2)  评论(0)    收藏  举报