“$\alpha(n)$ 增长极慢,却不是数学上的严格常数。可回滚 DSU通常禁用路径压缩,因为一次 Find 会改许多父指针,记录并撤销它们会破坏简单成本;它改用按大小合并的 $O(\log…”
形式陈述 ​
可回滚并查集是并查集的受限扩展:它保留 find/union 语义,同时记录足够的可逆修改,使状态只能按更新栈的逆序退回。
状态与接口 ​
使用 union by size/rank,不做路径压缩。Find 沿父指针到根,树高
不变量与复杂度 ​
每条历史记录恰好描述一次可逆原子修改,按逆序恢复后,父森林、size 和附加摘要都回到快照状态。Union、Find 最坏
直觉
Rollback DSU 牺牲路径压缩,让每次 union 只改常数字段,并把旧值按时间顺序压栈。快照只是一个栈长度;递归分支退出时逆序恢复到该边界,便能共享父状态而让兄弟子问题彼此隔离。
例子与边界
递归搜索例子 ​
在分治递归节点加入一批当前区间有效的边,进入孩子前保存栈长;孩子处理完 rollback 到该长度。左右孩子因此共享父节点状态,却不会互相泄漏修改。这比复制整个 DSU 状态节省空间和时间。
易错边界 ​
重复 union 两个已连通顶点不改变结构,但快照语义必须一致:可压一个 no-op 标记,或只以栈长度回滚并确保调用方不按 union 次数撤销。路径压缩会修改整条路径,若不逐项记录就无法恢复。rollback 只能撤销栈顶历史;任意版本查询属于持久化,任意过去编辑属于追溯结构。
推论与应用
可回滚摘要 ​
若每个分量还维护权重和、二分图 parity 或最小编号,union 时必须把所有被覆盖字段的旧值一并压栈。恢复顺序与写入相反,且只把小根挂到大根,保证 Find 最坏
历史栈空间与成功合并次数及附加字段数线性。深度优先分治中最大同时栈长通常为当前根叶路径所加入边数,而非所有递归节点边副本之和。
栈中究竟记录什么 ​
执行 union(a,b) 前先找两根 (被挂根, 旧父亲, 新根, 旧大小) 推栈。恢复时按相反顺序写回,不能重新调用 union 猜测旧状态。
一次递归搜索的状态轨迹是:
snap = history.length;- 应用当前节点代表的所有边;
- 递归访问子问题并回答叶查询;
rollback(snap),逐项弹栈到原长度。
按大小合并使 find 最坏
参考资料
- James Driscoll et al., Making Data Structures Persistent, JCSS, 1989.
- Erik D. Demaine, MIT 6.851 Advanced Data Structures, dynamic-graph notes on rollback union–find, accessed 2026.