题意
(n) 个点 (m) 条边的无向图,(k) 次询问保留图中编号在 ([l,r]) 的边的时候图中的联通块个数。强制在线。
(n,m,kle 2 imes 10^5)
题解
LCT 练习题,和这题有得一比
对于一组询问 (l,r),考虑每一条编号在 ([l,r]) 的编号为 (i) 的边 ((u,v)) 什么时候会造成贡献:不加在 ([1,l-1]) 的边,从小到大加入编号在 ([l,i-1]) 的边,(u) 和 (v) 在两个不同的连通块中。
那怎么判断加入这条边前, (u,v) 是否在两个不同的连通块中?考虑先不删编号在 ([1,l-1]) 的边,找一条 (u,v) 两点间编号最小的边的编号最大的路径,若这条路径上编号最小的边的编号(ge l),则 (u,v) 在同一连通块中,否则在不同连通块中。
问题就在于如何求这条路径,当然我们只需要这条路径上编号最小的边的编号。
这个可以用经典的贪心 + LCT。用一棵 LCT 维护动态 MST,按编号从小到大依次把边加入 LCT,若加边前两端已经连通,则取这两点在 MST 上的路径上编号最小的一条边,把它删掉换成现在加入的这条边即可。记录一下这条边换掉的边的编号 (lst_i)。若加边前两端不连通,则换掉的边的编号记为 (0)。
这样就求出了每条边在加入前,其两端 (u,v) 是否在不同的连通块中。
若加入一条边前,其两端点 (u,v) 不在同一连通块中,则加入这条边后连通块数 (-1)。
则询问的答案就是 (n - sumlimits_{i=l}^r [lst_i<l]),主席树维护即可。