可撤销并查集
前言
今天在吃饭的时候听 @Kenma 讲解了一遍,发现好像很好用而且很好写,就写了。
思路
拿栈存每次操作时被合并的父亲节点,撤销时直接将其指回自己,所以不能使用路径压缩,使用按秩合并。
只能离线。
可持久化并查集
发现如果访问某个历史版本时采用一步一步撤销回去太慢了。所以我们建立一棵版本树。
形象地说:想象一条以时间为节点的链,上面连着几条跨越时间的边,当我们访问到某个时间节点时,如果他有跨越时间的边,直接访问,然后正常进行操作即可。(有没有感觉很优美而且很有意境,学魔怔了)
具体而言:如果时间点 $i$ 不是操作 2 ,那就让时间点 $i$ 向 $i+1$ 连边,时间照常流转;如果时间点 $i$ 是操作 2 ,回到 $a_i$ 的时间点,那就让时间点 $a_i$ 向 $i$ 连边(过去向未来连),因为我们需要的是 $a_i$ 的版本。