线段树分治&可撤销并查集
可撤销并查集
按时间顺序用一个栈维护合并信息,撤销时从栈顶弹出合并信息,恢复原状态。
并查集查找祖先时 不能路径压缩,只能按秩合并。
例题:
[ABC302Ex] Ball Collector
容易想到将
遍历整棵树,用可撤销并查集维护图。
为了进一步求得答案,需要注意到该结论:对于一个连通块,对当前答案的贡献为
证明可以考虑从树的特殊情况出发,添加一条返祖边,分析贡献的变化。
于是简单地维护这两个量和答案即可。
Warning:在实现上的注意:
之前写可撤销并查集时只用栈维护了合并两个连通块时的操作(由于不是路径压缩,因此父亲在一段时间内是固定的,你甚至可以只记录大小较小的连通块的祖先编号),并没有把每一步操作都记录下来,这是因为我们需要的信息只与连通块内的点有关,因此不需要知道连通块内连接的具体形态。但在这道题里,我们需要查询边的信息,因此需要把每一步操作都存进栈里。
线段树分治
xht 的题解对该算法的叙述精辟而清晰:
考虑这样一个问题:
- 有一些操作,每个操作只在
的时间段内有效。 - 有一些询问,每个询问某一个时间点所有操作的贡献。
对于这样的询问,我们可以离线后在时间轴上建一棵线段树,这样对于每个操作,相当于在线段树上进行区间操作。
遍历整颗线段树,到达每个节点时执行相应的操作,然后继续向下递归,到达叶子节点时统计贡献,回溯时撤销操作即可。
这样的思想被称为线段树分治,可以在低时间复杂度内解决一类在线算法并不优秀的问题。
例题:(没放板题)
线段树分治与可撤销并查集
P5631 最小mex生成树
枚举答案
将边权视作时间进行分治。将边权为
空间复杂度
CF1681F Unique Occurrences
有了上面那道题的经验,这里仍然考虑 将边权视作时间进行分治。
对于颜色
CF1140F Extending Set of Points
难得独立做出来 *2600。按时间分治,关键是如何维护答案。
经典套路,将二维平面上的点
由于递归到叶子节点时统计答案的时间复杂度过高,可以 在并查集的合并与撤销时维护答案。
[ABC163F] path pass i
将点权视作时间进行分治,用线段树分治维护连通块信息。
如果按原题意操作,发现线段树递归到叶子节点时不方便统计答案,因此可以容斥一下,去求不包含颜色
去掉所有端点权值为
仍然是在并查集合并和撤销的过程中维护答案。
时间复杂度
本文作者:Schucking-Sattin
本文链接:https://www.cnblogs.com/Schucking-Sattin/p/17735787.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步