Skip to content

Commit

Permalink
fix(splay.md): 更正 Splay 树中的复杂度证明 (OI-wiki#6128)
Browse files Browse the repository at this point in the history
fix(splay.md): correct complexity analysis
  • Loading branch information
c-forrest authored Feb 11, 2025
1 parent 561e38d commit c08289e
Showing 1 changed file with 63 additions and 44 deletions.
107 changes: 63 additions & 44 deletions docs/ds/splay.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,101 +326,120 @@ void del(int k) {
## 时间复杂度
在 Splay 树中,由于 **zig** 和 **zag** 操作是对称的,因此我们只需分析 **zig**、**zig-zig** 和 **zig-zag** 三种操作的复杂度。为此,我们采用 **势能分析法**,通过研究势能的变化来推导操作的均摊复杂度。假设对一棵包含 $n$ 个节点的 Splay 树进行了 $m$ 次 splay 操作,可以通过以下定义和性质来进行分析
在 Splay 树中,由于 **zig** 和 **zag** 操作是对称的,因此我们只需分析 **zig**、**zig-zig** 和 **zig-zag** 三种操作的复杂度。为此,我们采用 **势能分析法**,通过研究势能的变化来推导操作的均摊复杂度。假设对一棵包含 $n$ 个节点的 Splay 树进行了 $m$ 次 splay 操作,可以通过如下方式进行分析
**定义**:
**定义**
1. **单个节点的势能**:$w(x) = \log(\text{size}(x))$,其中 $\text{size}(x)$ 表示以节点 $x$ 为根的子树大小。
2. **整棵树的势能**:$\varphi = \sum w(x)$,即树中所有节点势能的总和,初始势能满足 $\varphi(0) \leq n \log n$。
2. **整棵树的势能**:$\varphi = \sum w(x)$,即树中所有节点势能的总和,初始势能满足 $\varphi_0 \leq n \log n$。
3. **第 $i$ 次操作的均摊成本**:$c_i = t_i + \varphi(i) - \varphi(i-1)$,其中 $t_i$ 为实际操作代价,$\varphi(i)$ 和 $\varphi(i-1)$ 分别为操作后和操作前的势能。
3. **第 $i$ 次操作的均摊成本**:$c_i = t_i + \varphi_i - \varphi_{i-1}$,其中 $t_i$ 为实际操作代价,$\varphi_i$ 和 $\varphi_{i-1}$ 分别为操作后和操作前的势能。
**性质**:
**性质**
1. 如果 $fa$ 是 $x$ 的父节点,则有 $w(fa) \geq w(x)$,即父节点的势能不小于子节点的势能。
1. 如果 $p$ 是 $x$ 的父节点,则有 $w(p) \geq w(x)$,即父节点的势能不小于子节点的势能。
2. 由于根节点的子树大小在操作前后保持不变,因此根节点的势能在操作过程中不变。
3. 如果 $fa$ 的两个子节点分别是 $x$ 和 $y$,那么有 $2w(fa) - w(x) - w(y) \geq 2$
3. 如果 $\text{size}(p)\ge\text{size}(x)+\text{size}(y)$,那么有 $2w(p) - w(x) - w(y) \geq 2$
??? note "性质 3 的证明"
1. 设 $\text{size}(fa) = z$,$\text{size}(x) = y$,$\text{size}(y) = x$,则有 $z = x + y + 1$。
2. 因此,$2w(fa) - w(x) - w(y) = \log z^2 - \log y - \log x = \log \frac{z^2}{x \cdot y}$。
3. 带入 $z = x + y + 1$,可以推导出:$\log \frac{(x + y + 1)^2}{x \cdot y} > \log \frac{(x + y)^2}{x \cdot y} \geq \log 4 = 2$。
根据均值不等式可知
接下来,分别对 **zig**、**zig-zig** 和 **zig-zag** 操作进行势能分析。
$$
\begin{aligned}
2w(p) - w(x) - w(y)
&= \log\dfrac{\text{size}(p)^2}{\text{size}(x)\cdot\text{size}(y)} \\
&> \log\dfrac{\left(\text{size}(x)+\text{size}(y)\right)^2}{\text{size}(x)\cdot\text{size}(y)} \\
&\ge \log 4 \\
&= 2.
\end{aligned}
$$
**Zig**:根据性质 1 和 2,有 $w(fa) = w'(x)$,且 $w'(x) \geq w'(fa)$。由此,均摊成本为:
接下来,分别对 **zig**、**zig-zig** 和 **zig-zag** 操作进行势能分析。设操作前后的节点 $x$ 的势能分别是 $w(x)$ 和 $w'(x)$。节点的记号与 [上文](#splay-操作) 一致。
**zig**:根据性质 1 和 2,有 $w(p) = w'(x)$,且 $w'(x) \geq w'(p)$。由此,均摊成本为
$$
\begin{aligned}
c_i &= 1 + w'(x) + w'(fa) - w(x) - w(fa)\\
&= 1 + w'(fa) - w(x)\\
&\leq 1 + w'(x) - w(x)
c_i &= 1 + w'(x) + w'(p) - w(x) - w(p)\\
&= 1 + w'(p) - w(x)\\
&\leq 1 + w'(x) - w(x).
\end{aligned}
$$
**Zig-Zig**:根据性质 1 和 2,有 $w(g) = w'(x)$,且 $w'(x) \geq w'(fa)$,并且 $w(x) \leq w(fa)$。根据性质 3,可得:
**zig-zig**:根据性质 1 和 2,有 $w(g) = w'(x)$,且 $w'(x) \geq w'(p)$,$w(x) \leq w(p)$。因为
$$
2 \cdot w'(x) - w(x) - w'(g) \geq 2
\begin{aligned}
\text{size}'(x)
&= 3 + \text{size}(A) + \text{size}(B) + \text{size}(C) + \text{size}(D) \\
&> (1 + \text{size}(A) + \text{size}(B)) + (1 + \text{size}(C) + \text{size}(D)) \\
&= \text{size}(x) + \text{size}'(g),
\end{aligned}
$$
由此,均摊成本为:
根据性质 3 可得
$$
c_i = 2 + w'(x) + w'(fa) + w'(g) - w(x) - w(fa) - w(g)
2 w'(x) - w(x) - w'(g) \geq 2.
$$
简化后:
由此,均摊成本为
$$
\begin{aligned}
c_i &= 2 + w'(fa) + w'(g) - w(x) - w(fa)\\
&\leq 2w'(x) + w'(fa) - 2w(x) - w(fa)\\
&\leq 3 \cdot (w'(x) - w(x))
c_i &= 2 + w'(x) + w'(p) + w'(g) - w(x) - w(p) - w(g) \\
&= 2 + w'(p) + w'(g) - w(x) - w(p) \\
&\le (2 w'(x) - w(x) - w'(g)) + w'(p) + w'(g) - w(x) - w(p) \\
&= 2(w'(x)-w(x)) + w'(p) - w(p) \\
&\le 3(w'(x)-w(x)).
\end{aligned}
$$
**Zig-Zag**:根据性质 1 和 2,有 $w(g) = w'(x)$,且 $w(fa) \geq w(x)$。根据性质 3,可得:
$$
2 \cdot w'(x) - w'(g) - w'(fa) \geq 2
$$
由此,均摊成本为:
**zig-zag**:根据性质 1 和 2,有 $w(g) = w'(x)$,且 $w(p) \geq w(x)$。因为 $\text{size}'(x)>\text{size}'(p)+\text{size}'(g)$,根据性质 3,可得
$$
c_i = 2 + w'(x) + w'(fa) + w'(g) - w(x) - w(fa) - w(g)
2 \cdot w'(x) - w'(g) - w'(p) \geq 2.
$$
简化后:
由此,均摊成本为
$$
\begin{aligned}
c_i&= 2 + w'(g) + w'(fa) - w(x) - w(fa)\\
&\leq 2 \cdot w'(x) - w(x) - w(fa)\\
&\leq 2 \cdot (w'(x) - w(x))
c_i &= 2 + w'(x) + w'(p) + w'(g) - w(x) - w(p) - w(g) \\
&= 2 + w'(p) + w'(g) - w(x) - w(p) \\
&\le (2w'(x) - w'(g) - w'(p)) + w'(p) + w'(g) - w(x) - w(p) \\
&= 2w'(x) - w(x) - w(p) \\
&\le 2(w'(x) - w(x)).
\end{aligned}
$$
**总结**:
**单次 Splay 操作**:
由此可见,三种 splay 步骤的均摊成本全部可以缩放为 $\leq 3(w'(x)−w(x))$. 令 $w^{(n)}(x)=w'^{(n-1)}(x)$,$w^{(0)}(x)=w(x)$, 假设一次 splay 操作依次访问了 $x_{1}, x_{2}, \cdots, x_{n}$, 最终 $x_{1}$ 成为根节点,我们可以得到:
令 $w^{(n)}(x)=(w^{(n-1)})'(x)$$w^{(0)}(x)=w(x)$假设一次 splay 操作依次访问了 $x_{1}, x_{2}, \cdots, x_{n}$ 等节点,最终 $x_{1}$ 成为根节点。这必然经过若干次 **zig-zig** 和 **zig-zag** 操作和至多一次 **zig** 操作,前两种操作的均摊成本均不超过 $3(w'(x)-w(x))$,而最后一次操作的均摊成本不超过 $3(w'(x) - w(x))+1$,所以总的均摊成本不超过
$$
\begin{aligned}
3\left(\sum_{i=0}^{n-2}\left(w^{(i+1)}(x_{1})-w^{(i)}(x_{1})\right)+w(n)−w^{(n-1)}(x_{1})\right)+1 & = 3(w(n)−w(x_{1}))+1 \\
& \leq \log n
\end{aligned}
3(w^{(n)}(x_1) - w^{(0)}(x_1)) + 1 \le 3\log n + 1.
$$
继而可得:
因此,一次 Splay 操作的均摊复杂度是 $O(\log n)$ 的。从而,基于 splay 的插入、查询、删除等操作的时间复杂度也为均摊 $O(\log n)$。
??? info " 为什么 Splay 树的再平衡操作可以获得 $O(\log n)$ 的均摊复杂度?"
朴素的再平衡思路就是对节点反复进行旋转操作使其上升,直到它成为根节点。这种朴素思路的问题在于,对于所有子节点都是左(右)节点的链状树来说,它相当于反复进行 **zig** 操作,因而 **zig** 操作的均摊复杂度中的常数项 $1$ 会不断累积,造成最终的均摊复杂度达到 $O(\log n+n)$ 级别。Splay 树的再平衡操作的设计,避免了连续 **zig** 的情形中的常数累积,使得一次完整的 Splay 操作中,至多进行一次单独的 **zig** 操作,从而优化了时间复杂度。
**结论**:
在进行 $m$ 次 Splay 操作之后,实际成本
$$
\sum_{i=1}^m (\varphi (m-i+1)−\varphi (m−i)) +\varphi (0) = n \log n+m \log n
\begin{aligned}
\sum_{i=1}^m t_i &= \sum_{i=1}^m \left(c_i + \varphi_{i-1} - \varphi_i \right) \\
&= \sum_{i=1}^m c_i + \varphi_0 - \varphi_m \\
&\le m(3\log n+1) + n\log n.
\end{aligned}
$$
因此,对于 $n$ 个节点的 splay 树,做一次 splay 操作的均摊复杂度为 $O(\log n)$。从而基于 splay 的插入,查询,删除等操作的时间复杂度也为均摊 $O(\log n)$。
因此,$m$ 次 Splay 操作的实际时间复杂度为 $O((m+n)\log n)$。
## 实现
Expand Down

0 comments on commit c08289e

Please sign in to comment.