大年初一奖励自己把这段分析啃下来。
并查集结构表示
- 令集合 \(S\) 表示并查集中所有点;
- 令集合 \(T\) 表示所有作为根的节点。
阿克曼函数
我们定义阿克曼函数 \(A_k\) 为:
这里,\(f^i(x)\) 表示将 \(f\) 连续应用在 \(x\) 上 \(i\) 次,即 \(f^0(x)=x,f^i(x)=f(f^{i-1}(x))\)。
再定义反阿克曼函数 \(\alpha(n)\) 为使 \(A_{\alpha(n)}(1)\ge n\) 成立的最小整数值。
势能函数定义
令每个节点维护一个值 \(\mathtt{rank}\);每个节点的初始 \(\mathtt{rank}\) 定义为 \(0\)。在合并(union)时,若两个节点的 \(\mathtt{rank}\) 不同,将 \(\mathtt{rank}\) 较小的节点合并到 \(\mathtt{rank}\) 大的节点上;否则,任意将一个节点合并到另一个节点上,并令根节点(被合并的节点)的 \(\mathtt{rank}\) 值加一;查询(find)时不对 \(\mathtt{rank}\) 进行操作。这里 \(\mathtt{rank}\) 表示每个点作为根的子树深度的一个上界。记 \(x\) 节点的 \(\mathtt{rank}\) 为 \(r(x)\),类似地,记 \(x\) 的父节点为 \(f(x)\);总有 \(r(x)+1\le r(fa(x))\)。
为了定义势函数,先定义辅助函数 \(l(x)\):
当 \(r(x)>1\) 时,再定义 \(i(x)\) 为:
这两个函数均满足 \(x\) 不是某个树的根且 \(r(x)\gt 0\),方便起见,若 \(x\) 是某个树的根或 \(r(x)=0\),定义 \(l(x)=i(x)=0\)。
显然 \(l(x)\) 随操作的进行单调不降;同时,在 \(l(x)\) 不增的情况下,\(i(x)\) 单调不降。并且:
以上内容由定义显然,不证。
定义一个点 \(x\) 的势能 \(\Phi(x)\) 为:
定义整个并查集 \(S\) 的势能 \(\Phi(S)\) 定义为每个节点势能的和,即:
容易发现,势能非负且初始状态下势能为 \(0\)。
下面证明均摊复杂度。
势能变化
先考虑任意一个 \(x\not\in T\) 且 \(r(x)>0\),设操作前势能为 \(\Phi(c)\),操作后的势能为 \(\Phi(c')\),只有三种情况:
- \(i(c)\) 和 \(l(c)\) 不变。显然 \(\Phi(c)=\Phi(c')\)。
- \(l(c)\) 不变,\(i(c)\) 增加。由于 \(i(c)\) 至少增加 \(1\),有 \(\Phi(c')\le \Phi(c)-1\)。
- \(l(c)\) 增加,此时 \(i(c)\) 可能减少,但显然最多减少 \(r(c)-1\),而 \(l(c)\) 至少增加 \(1\),由定义可得 \(\Phi(c')\le \Phi(c)-1\)。
总之,对于任意 \(x\not\in T\) 且 \(r(x)>0\),在单次操作后势能单调不增;更强地,若节点 \(x\) 的 \(i(c)\) 或 \(l(c)\) 有变化,则操作后势能至少减 \(1\)。
union(x,y) 操作
方便起见,这里假设 \(x,y\in T\)。
显然所需时间为 \(\Theta(1)\),考虑其引起的势能变化。
这里假设 \(y\) 是新的根节点,即 \(r(x)\le r(y)\)。
显然只有三种点的势能可能变化:
- 节点 \(x\)(由树根变为非树根);
- 节点 \(y\)(\(\mathtt{rank}\) 可能增加);
- 操作前 \(y\) 的子节点(父节点的 \(\mathtt{rank}\) 可能增加)。
其中第三类节点在上文已经讨论过。
节点 \(x\) 由树根变为非树根,\(l(x)\) 和 \(i(x)\) 都不会减少,故 \(\Phi(x')\le \Phi(x)\)。
节点 \(y\) 的 \(\mathtt{rank}\) 至多加一,而 \(\Phi(y)=\alpha(n)\cdot r(y)\),故 \(y\) 的势能最多增加 \(\alpha(n)\)。
综上,进行 \(\mathtt{union}\) 操作后,总的势能最多增加 \(\alpha(n)\),故均摊复杂度为 \(\Theta(\alpha(n))\)。
find(a) 操作
若查找路径包含 \(s\) 个节点,显然查找的时间复杂度为 \(\Theta(s)\)。只需证明总势能至少减 \(s-\alpha(n)\),即可证明均摊复杂度为 \(\Theta(\alpha(n))\)。
显然任意 \(x\in T\) 的势能不变,而其他节点的势能不增,故没有节点的势能增加。
只需证明有 \(s-\alpha(n)\) 个节点的 \(l(x)\) 或 \(i(x)\) 有改变。
设 \(t(x)\) 为 \(x\) 所处的树的根节点,只需证 \(r(t(x))\ge A^{i(x)+1}_{l(x)}(r(x))\) 即可。
即:
显然只需要找到一个 \(y\) 是 \(x\) 的祖先(且不是树根),满足 \(l(y)=l(x)\) 即可。
显然存在一些 \(x\) 不满足要求,但由于不同的 \(l(x)\) 只有 \(\alpha(n)\) 个,最多只有 \(\alpha(n)\) 个节点不满足要求。
也就是说,至少有 \(s-\alpha(n)\) 个节点的势能会改变,也即总势能至少减 \(s-\alpha(n)\)。