线段树分治 笔记
功能
用来离线的维护一个图的连通性,可以动态的维护出并查集。然而并查集的复杂度并不是 \(O(\alpha(n))\),而是 \(O(\log n)\),因为不能路径压缩。
可以被LCT+ETT吊打。但是对于写不熟练或者不会写LCT的(像我这样的)新手来说,这个可以帮我们拿到更多分。而且由于我们可以动态的维护出并查集,还可以更方便的求出与联通块有关的各种信息————维护连通性,联通块的size,权值的和(平方和,积,方差,XOR和...),最大异或和(维护一个线性基),等等。
实现
现在要支持一些加边和删边的操作。
考虑每条边,它都会有若干个“存活区间”,即在这些时间区间上,它在这个图中;否则它不在这个图中。
然后考虑对于时间(第几个操作)开线段树。对于每条边的每个存活区间,把它分解成线段树区间,打到线段树上。
然后遍历一遍线段树。对于当前节点,把打在这个节点上的边加进来,递归处理儿子;离开这个点的时候把边 撤销。
于是要维护一个可撤销的并查集,这就是为啥不能路径压缩。不路径压缩之后,开一个栈,栈节点是一个struct,存储修改的位置,以及它原来的值 (fa,cnt数组)。撤销的时候就取栈顶,把它记录的信息复原就可以了,很simple。
这样就把加边变成了普通的加边,删边全部变成了撤销操作。从“存活区间”的覆盖角度来考虑发现,我们确实可以求出每个时刻都有哪些边(的存活区间覆盖了这个时刻)。
模板就是loj上动态图连通性的模板,离线可过的那个。