基于替罪羊树维护的 K‑D Tree 复杂度证明

· · 算法·理论

UPD on Jul 22: fix typo & 添加 U 群相关讨论

摘要

本文证明了替罪羊树维护 K‑D Tree 的查询、重构复杂度,打破算法竞赛社区关于该做法复杂度的错误观点。

This article proves the query and reconstruction complexity of the scapegoat tree maintaining a K‑D Tree, refuting the incorrect belief in the competitive programming community regarding the complexity of this approach.

:::info[U 群关于这个的讨论节选(2026-07-22)]

MZMTab 2026-07-20 17:37:48
vuqa,https://www.luogu.com.cn/article/shh0v8zb

qqwq 2026-07-20 17:43:33
@MZMTab ok

qqwq 2026-07-20 17:43:40
kdt这一段oiwiki是我写的

qqwq 2026-07-20 17:44:21
但是你好像没有提出新东西啊

qqwq 2026-07-20 17:44:31
没有保证,只是不保证是根号的

qqwq 2026-07-20 17:44:37

MZMTab 2026-07-20 17:44:59
好像要这么说也有道理

qqwq 2026-07-20 17:46:40
如果你认为这个有歧义的话,这里确实可以改一下

qqwq 2026-07-20 17:47:53
不过我觉得做了这个工作还是值得认可的也可以把它提交到oiwiki()

MZMTab 2026-07-20 17:48:10
主要是看网上没人写

gxy 2026-07-20 17:48:24
这个不是常识吗

gxy 2026-07-20 17:48:46
https://www.luogu.com/article/cod5s33o ,远古blog早有记载

gxy 2026-07-20 17:49:25
感觉我学的时候,周边人都知道这是

MZMTab 2026-07-20 17:49:55
emmm

MZMTab 2026-07-20 17:52:17
似乎有点瑕疵,没有 akra-bazzi后面的积分项的分析

qqwq 2026-07-20 17:54:07
就是他觉得,这个没保证,是指可能退化成暴力

:::

前言

很多选手会使用替罪羊树结构来维护.但是注意到在刚才的复杂度分析中,要求儿子的子树大小严格减半,即树高必须为严格的 \log n+O(1),而替罪羊树只满足树高 O(\log n),故查询复杂度无法保证. ——OI wiki K‑D Tree

我写完后估计就要改了

本文的目的即证明使用替罪羊树维护 K‑D Tree 的复杂度。其中,本文重点分析二维情况。

如果你并不了解这一做法,可以参考 aaron0919 的 P14312 【模板】K-D Tree の题解,但是其中的复杂度证明是错误的,详细原因请参考后文

本文仅讨论交错建树。对于二维而言,即建树时每层的排序方式即按 x 坐标排序与按 y 坐标排序交替。

前置知识

我们会使用的工具:

  1. 均摊分析和替罪羊树的复杂度证明
  2. Akra‑Bazzi 定理,可以参考 GONGGONGJOHN 的从主方法到Akra-Bazzi定理

Akra‑Bazzi 定理

现不加证明地给出 Akra‑Bazzi 定理:

f(x) 为非负函数,

T(n)= \begin{cases} \Theta(1) ,1 \le n \le X_0\\ \sum \limits_{i=1}^k a_i \cdot T(b_i n) +f(n) \ ,n \gt X_0 \end{cases}

满足

\forall 1 \le i \le k,a_i \gt 0,0\lt b_i \lt 1, X_0 \gt \frac{1}{1-b_i},f(n)\text{ 满足多项式增长条件}

对于定义在非负实数的函数 f(n),称 f(x) 满足多项式增长条件当且仅当 \exists c_1,c_2>0,\{b_k\},b_i \in(0,1),\forall x \ge 1,1 \le i \le k,u \in [b_i x,x],c_1 f(x) \le f(u) \le c_2 f(x)

由定义可知,若存在 c \ge 0,使得 |g^\prime(x)| \in \mathcal{O}(n^c),则 g(x) 满足多项式增长条件。

特别地,a,b\in \mathbb R,f(n)= \mathcal{O}(n^a\log ^b n),则 f(n) 满足多项式增长条件。

T(n) = \Theta \left (n^p \left (1+\int _1^n \frac{f(x)}{x^{p+1}} dx\right)\right )

其中 p 为方程 \sum \limits _{i=1}^k a_i b_i ^p =1 的实数根。

:::info[为什么和论文 [1] 中的描述不一样]

我本来是想要用论文 [1] 中的版本,但是我看到里面有这样一句话:

g(x)$ is defined for real values $x$, and is bounded, positive and nondecreasing function $\forall x \ge 0

此处的 g(x) 即上文的 f(x)

注意到其中有一个 bounded,非常奇怪,因为连 g(n)=n 都不满足,这不合理。于是检索发现参考资料 [5] 的问答,接着查阅了参考资料 [4] 中 Leighton 的讲义,认为 bounded 是个 typo。

由于参考资料 [4] 中的描述 "These conditions are somewhat less restrictive than those of [1]",且为互联网上最常见的描述,所以选择了这种描述。

:::

关于平衡树相关的一些术语

但是 $\alpha$‑高度平衡不能推出 $\alpha$‑重量平衡。举一个反例左子树为深度为 $k$ 的链,大小为 $k$;右子树为深度为 $k$ 的完全二叉树大小为 $2^k-1$,整棵树总结点树为 $2^k+k$。当 $k$ 足够大时,对于任意 $\alpha>0.5$,这颗树可以满足 $\alpha$‑高度平衡;但左右子树差异极大,无法满足 $\alpha$‑重量平衡。 ## 完全平衡时的查询复杂度证明 借鉴了 [OI wiki K‑D Tree](https://oi-wiki.org/ds/kdt/#%E5%A4%8D%E6%9D%82%E5%BA%A6%E5%88%86%E6%9E%90) 的证明。 先考虑二维情况。 若查询的矩形为 $R$,让我们考虑一个结点代表的矩形 $P$ 有以下三种情况: 1. $R$ 完全包含 $P$; 2. $R$ 和 $P$ 相离; 3. $P$ 完全包含 $R$; 4. $P$ 与 $R$ 相交但互不包含。 其中 3 和 4 两种情况是要继续递归的,即复杂度为 3 和 4 两种情况的结点数之和。 而第 3 种情况有一个平凡的上限:$\mathcal{O}(h)=\mathcal{O}(\log n)$,$h$ 为树高。 重点来考虑第 4 种情况。由于位于第 4 种情况时,一定在矩形的边缘。我们需要统计的总点数一定小于四个条边上的矩形个数和。 每个结点会的四个孙子结点将该矩形分为四个子矩形。而一条线段只能通过这其中的两个子矩形,所以可以得到这部分的递归式: $$ T(n)= 2 T(\frac{n}{4}) +\Theta (1) $$ 由主定理解得 $$ T(n) = \Theta(\sqrt n) $$ 这个大于 $\mathcal O(\log n)

类似地分析可以得到 k 维的情况:

T(n)= 2^{k-1}T(\frac{n}{2^k}) + \Theta(1)

由主定理,得到经典结论:

T(n)= \Theta(n ^{\frac{k-1}{k}})

替罪羊树维护的查询复杂度证明(二维情况)

有了上面的基础,我们可以考虑在替罪羊树上有什么不同。

可以发现,唯一的区别就是划分出来的四个子矩形大小不相同。

考虑一种极端情况:所有子树都恰好满足 \alpha‑重量平衡。为了方便我们假设现在讨论的子树大小为 n。那么四个孙子结点的子树的大小分别为:

\alpha ^2 n,\alpha(1-\alpha)n,\alpha(1-\alpha)n,(1-\alpha)^2n

取其中最大的两个,得到递归式:

T(n)=T(\alpha^2n)+T(\alpha(1-\alpha)n)+ \Theta(1)

可以直接套用 Akra‑Bazzi 定理。

我们先讨论一个特殊情况:\alpha=0.6=\frac{3}{5}

\left(\frac{9}{25}\right) ^p + \left( \frac{6}{25}\right)^p=1

这是一个超越方程,没有初等函数通式解。通过二分等方法可以解得

p \approx 0.57

\int _1 ^n \frac{1}{x^{p+1}} dx = \left(\frac{x^{-p}}{-p} \right)^n _{1} = \frac{1}{p}\left( 1- n^{-p} \right) \le \frac{1}{p} =\Theta(1)

故总复杂度为

T(n)= \Theta(n^p) \approx \Theta(n^{0.57})

而在 OI 可能的数据范围内(n \le 10^6),n^{0.07} \le 2.63,这个复杂度和 \Theta(\sqrt n) 几乎没有区别

更一般地,考虑函数

g(x)= \alpha^{2x}+ (\alpha(1-\alpha)) ^x -1

考察参数 \alpha 的取值对零点的影响。

由于 \alpha \in (0.5,1)g(x)\mathbb R_{+} 单调递减。故函数有唯一零点。

g(0.5)= \alpha + \sqrt {\alpha(1-\alpha)} -1

我们猜想 g(0.5) >0,这等价于

\sqrt {\alpha(1-\alpha)}>1 - \alpha

左右显然都是正的。两边平方,得

\alpha(1-\alpha) >(1-\alpha)^2

同时除以正数 1-\alpha,得

\alpha > 1- \alpha \Leftrightarrow \alpha > 0.5

显然成立。故当 \alpha \in (0,5,1) 时,g(0.5)>0

g(1)=\alpha^2+\alpha(1-\alpha)-1=\alpha-1<0

p \in(0.5,1)

\int _1 ^n \frac{1}{x^{p+1}} dx = \left(\frac{x^{-p}}{-p} \right)^n _{1} = \frac{1}{p}\left( 1- n^{-p} \right) \le \frac{1}{p} =\Theta(1)

故复杂度为

T(n)=\Theta(n^p)

\alpha \in(0.5,0.75] 时,p \in (0.5,0.68]。而 (10^5)^{0.18} \le 8,在 OI 中可以视为常数。

通过观察 \alpha-p 图像,我发现这个超越函数在 (0.5,0.9) 几乎为线性,线性回归得到 p(\alpha)\approx 0.7002\alpha +0.1511,在 (0.5,0.9) 的误差在小数点后三位,几乎可以忽略。这样,计算复杂度时就没有必要解超越方程了。

所以,替罪羊树维护的 K‑D Tree 复杂度是有保障的,只是比根号略微高一点。这就是为什么大家认为其复杂度错误但多年来没有人成功地 Hack 的原因。

一个伪证的批驳

在上述介绍替罪羊树维护 K‑D Tree 的文章 aaron0919 的 P14312 【模板】K-D Tree の题解中,其证明最重要的是这个式子:

\sum_{i=0} ^{\frac{h}{2}} 2^i \approx 2^{\frac{h}{2}} \approx 2 ^{\frac{\log _2 n}{2}} = \sqrt n

现不考虑其没带 \Theta\mathcal{O} 的不严谨。其核心错误在于第二个约等号:

2^{\frac{h}{2}} \approx 2^{\frac{\log _2 n}{2}}

由于替罪羊树是只能保证 \alpha‑高度平衡,树高可以达到

h=\log _{\alpha^{-1}} n = \frac{\log _2 n}{\log _2 {(\alpha ^{-1})}}

则代入得

2^{\frac{h}{2}}= 2^{\frac{\log _2 n}{2\log _2 {(\alpha ^{-1})}}} =n ^{\frac{1}{2\log _2 {(\alpha^{-1})}}}

比如代入 \alpha=0.6,得到复杂度约为 \Theta(n^{0.68});代入 \alpha=0.75,得到复杂度约为 \Theta(n^{1.20}):这个结果明显劣于上面的分析,更不是其所称的根号。而且即使修正后 \alpha 稍大时复杂度就超过平凡的上界 \mathcal{O}(n),没有很大的实际价值。

替罪羊树的重构复杂度证明

替罪羊树满足

\max(\text{size}(left), \text{size}(right)) \le \alpha \cdot \text{size}(parent)

否则会进行重构。

重构完成的瞬间,子树满足 \frac{1}{2}‑重量平衡,左右子树大小相差最多为 1

我们现在考虑:从一个刚刚重构好了的满足 \frac{1}{2}‑重量平衡的子树,至少要插入 d 给点才会使得这个这个子树不满足 \alpha‑重量平衡。

设当前子树大小为 n,其中左子树大小就为 \lceil{\frac{n-1}{2}}\rceil,右子树大小为 \lfloor\frac{n-1}{2}\rfloor。最极端的情况是所有的都插入到同一个左子树中。那么当该子树不满足 \alpha‑重量平衡时,满足:

\begin{align*} \left\lceil{\frac{n-1}{2}}\right\rceil+s&>\alpha (n+s)\\ \end{align*}

\left\lceil{\frac{n-1}{2}}\right\rceil 放缩为 \frac{n}{2}

\begin{align*} \frac{n}{2}+s&>\alpha (n+s)\\ \frac{n}{2}+s&>\alpha n+ \alpha s\\ (1- \alpha)s &>(\alpha-0.5) n\\ s &> \frac{\alpha-0.5}{1-\alpha} n \end{align*}

这是一个下界。记 c=\frac{\alpha-0.5}{1-\alpha}

而重建一个大小为 n 的子树所用时间为 \Theta(n\log n)。(按 nth_element 的平均复杂度为线性计算,如果追求严格可以使用 median of medians 算法,但常数较大)

得到重构的代价为 \frac{\Theta(n \log n)}{s} \lt \frac{\Theta(n \log N)}{cn}=\mathcal{O}(\frac{(1-\alpha)\log N}{\alpha-0.5}),其中 N 为整棵树最多的结点树,显然 N \ge n

这样,单次重构时路径上每个点的均摊代价为 \mathcal{O}(\frac{(1-\alpha) \log N}{\alpha-0.5})

而插入时还经过 \log _{\alpha ^{-1}} N 个点,故总共的代价为 \mathcal{O}(\frac{1-\alpha}{\alpha-0.5}\log N \log_{\alpha^{-1}} N)。证毕。

由于插入找到一个数位置的复杂的为 \mathcal{O}(\log _{\alpha ^{-1}} {N}),相对于重构可以忽略。

\alpha 的最优取值

我们求出了修改、查询的复杂度,这可以指导我们求 \alpha 的理论最优值。

假设插入、查询比例为 1:1,则我们可以得到一个函数:

C(n,\alpha)=n ^{p(\alpha)} + \frac{1-\alpha}{\alpha -0.5} \log _2 n \log _{\alpha ^{-1}} {n}

在固定 n=10^5 时,\alpha \approx 0.63 时最优。

实践中可以根据表现和常数调参,建议以 \alpha = 0.6= \frac{3}{5} 开始。

高维情况

从一个上述四类点向下深度为 k 会划分成从一个 k 维超立方体划分成 2^k 个子 k 维超立方体,大小依次为 (\alpha+(1-\alpha))^k 二项式展开的结果。

k 为奇数,最大的 2^{k-1} 个为 \binom{k}{0}\alpha ^k\binom{k}{1}\alpha ^{k-1} (1-\alpha),一直到 \binom{k}{\frac{k-1}{2}}\alpha ^{\frac{k+1}{2}}(1- \alpha)^{\frac{k-1}{2}}

复杂度为

T(n)= \sum _{i=0} ^{\frac{k-1}{2}} \binom{k}{i} T(\alpha^{k-i}(1-\alpha)^{i}n) + \Theta (1)

Akra‑Bazzi 方程为:

\sum _{i=0} ^{\frac{k-1}{2}} \binom{k}{i} (\alpha^i(1-\alpha)^{k-i}) ^p =1

这个超越方程没有初等通式解,也不好分析。考虑三维情况:

\alpha ^{3p} + 3(\alpha ^2 (1-\alpha))^p=1

这也没有初等通式解。代入 \alpha=0.6,解得 p \approx 0.76;代入 \alpha=0.7,解得 p \approx 0.85:这时复杂度已经很高了,建议根据实际表现适当调小 \alpha

k 为偶数时,可得递归式

T(n)= \sum _{i=0} ^{\frac{k}{2}-1} \binom{k}{i}T( \alpha ^{k-i}(1-\alpha)^in) + \frac{1}{2} \binom{k}{\frac{k}{2}} T(\alpha^{\frac{k}{2}} (1-\alpha)^{\frac{k}{2}}n)

k 为任意值时实在难以分析,且 k 较大时和暴力差距不大,故略去。

一些留给读者的开放问题

  1. 建树时可能还有另一种方法——方差划分——这种方法使用替罪羊树维护是否能证明其复杂度有保障?
  2. 本文表明不完全平衡的 K‑D Tree 复杂度仍然可能有保证,那么能否换用其他的平衡树维护?

参考资料

  1. Akra M , Bazzi L .On the Solution of Linear Recurrence Equations[M].Kluwer Academic Publishers,1998.
  2. Galperin I , Rivest R L .Scapegoat Trees[J].DBLP, 1993.DOI:10.1145/313559.313676.
  3. OI Wiki 上的 K‑D Tree 和替罪羊树的复杂度证明
  4. Leighton T. Notes on better master theorems for divide-and-conquer recurrences. MIT Lecture Notes, 1996. 这是一份 MIT 的讲义。可以在 MIT 官方课程网站获得。
  5. 一个关于 Akra‑Bazzi 定理适用条件的问答:asymptotics - Why does Akra-Bazzi need that toll-function g is bounded? - Computer Science Stack Exchange
  6. aaron0919 的 P14312 【模板】K-D Tree の题解
  7. GONGGONGJOHN 的 从主方法到Akra-Bazzi定理

本文可能火药味比较足,敬请谅解。如有错误,欢迎批评指正