线段树分治&可撤销并查集

可撤销并查集

按时间顺序用一个栈维护合并信息,撤销时从栈顶弹出合并信息,恢复原状态。

并查集查找祖先时 不能路径压缩,只能按秩合并

例题:

[ABC302Ex] Ball Collector

容易想到将 \(A_i\)\(B_i\) 之间连边。

遍历整棵树,用可撤销并查集维护图。

为了进一步求得答案,需要注意到该结论:对于一个连通块,对当前答案的贡献为 \(\min(\text{点数}, \text{边数})\)。([ARC111B] Reversible Cards

证明可以考虑从树的特殊情况出发,添加一条返祖边,分析贡献的变化。

于是简单地维护这两个量和答案即可。

Warning:在实现上的注意:

之前写可撤销并查集时只用栈维护了合并两个连通块时的操作(由于不是路径压缩,因此父亲在一段时间内是固定的,你甚至可以只记录大小较小的连通块的祖先编号),并没有把每一步操作都记录下来,这是因为我们需要的信息只与连通块内的点有关,因此不需要知道连通块内连接的具体形态。但在这道题里,我们需要查询边的信息,因此需要把每一步操作都存进栈里。

线段树分治

xht 的题解对该算法的叙述精辟而清晰:

考虑这样一个问题:

  • 有一些操作,每个操作只在 \(l \sim r\) 的时间段内有效。
  • 有一些询问,每个询问某一个时间点所有操作的贡献。

对于这样的询问,我们可以离线后在时间轴上建一棵线段树,这样对于每个操作,相当于在线段树上进行区间操作。

遍历整颗线段树,到达每个节点时执行相应的操作,然后继续向下递归,到达叶子节点时统计贡献,回溯时撤销操作即可。

这样的思想被称为线段树分治,可以在低时间复杂度内解决一类在线算法并不优秀的问题。

例题:(没放板题)

线段树分治与可撤销并查集

P5631 最小mex生成树

枚举答案 \(x\),将所有权值为 \(x\) 的边删除,若剩下的边能够形成生成树(即图联通),说明原图上至少存在一棵生成树的 \(mex\)\(\le x\),即答案 \(\le x\)。则最小使图连通的 \(x\) 即为答案。

将边权视作时间进行分治。将边权为 \(x\) 的出现时段分成 \([0, x - 1]\)\([x + 1, \infin]\),最小使图连通的时间点即为答案。

空间复杂度 \(O(m\log{w})\),时间复杂度 \(O(m\log{n}\log{w})\)。(?

CF1681F Unique Occurrences

有了上面那道题的经验,这里仍然考虑 将边权视作时间进行分治

对于颜色 \(c\),将所有权值为 \(c\) 的边删除后形成若干连通块,原树上权值为 \(c\) 的边 \(x\) 所连的两个连通块的乘积即为通过 \(x\) 做出的贡献。

CF1140F Extending Set of Points

难得独立做出来 *2600。按时间分治,关键是如何维护答案。

经典套路,将二维平面上的点 \((x, y)\) 视作 \(x\)\(y + N\) 之间连无向边,则答案为所有连通块内横坐标点数与纵坐标点数的乘积之和。

由于递归到叶子节点时统计答案的时间复杂度过高,可以 在并查集的合并与撤销时维护答案

[ABC163F] path pass i

将点权视作时间进行分治,用线段树分治维护连通块信息。

如果按原题意操作,发现线段树递归到叶子节点时不方便统计答案,因此可以容斥一下,去求不包含颜色 \(c\) 的路径数 \(cnt\)

去掉所有端点权值为 \(c\) 的边,每个大小为 \(x\) 的连通块内对 \(cnt\) 贡献 \(\binom{x}{2} + x\)(注意此题中单点也算一条路径),但是切掉边后形成的颜色为 \(c\) 的单点不会做贡献,因此算的时候要把这部分去掉。

仍然是在并查集合并和撤销的过程中维护答案。

时间复杂度 \(O(n\log^{2}{n})\),但此题有线性做法。

posted @ 2023-09-28 14:46  Schucking_Sattin  阅读(217)  评论(0编辑  收藏  举报