[Ynoi2077] hlcpq

发布时间 2023-12-11 20:36:28作者: zhouhuanyi

注意到虽然图比较稠密,但是我们可以只保留一些有用的边。先考虑一个弱化版,找到一些有效的边构成的 \(G'\) 使得 \(G\)\(G'\) 连通性相同,实际上如果我们按某个坐标进行扫描线,原问题相当于维护一个集合 \(S\),支持:

\(1.\) 动态在 \(S\) 集合中加删点。

\(2.\)\(x\) 向所有 \(S\) 集合内 \([l,r]\) 的点连边。

实际上我们可以将 \(2\) 改写为,\(x\)\(S\) 集合中 \([l,r]\) 的其中一个点连边,再将 \(S\) 集合内 \([l,r]\) 的所有点相邻两个之间连边,由于每次加点只会增加 \(2\) 个相邻点对,删点只会增加一个相邻点对,所以总的相邻点对的个数是 \(O(n)\) 的,而一个相邻点对之间连了边后就没有必要再连了,所以如果这样的相邻点对可以直接删除。

于是我们用 \(\text{set}\) 可以动态维护所有未被删除的相邻点对,每次在 \(\text{set}\) 上查取所有 \([l,r]\) 的相邻点对连边并删除,每次加删点时动态更新相邻点对即可。但是如果我们将其直接扩展到本题会有一个问题,因为 \(G\)\(G'\) 的双连通性不同,所以一个原本不是割点的点会被误判成割点,考虑如何处理这个情况。

注意到原图是二分图,我们不妨先 \(\text{fix}\) 当前 \(S\) 的点是不统计的,两侧分别统计一边即可统计全部,那么我们考虑如何使得在保留双连通性的前提下不会使 \(G'\) 很大。而我们发现此时我们只关心 \(S\) 内部的双连通性,\(S\) 内部是不会删除的,所以我们可以只对相邻点对之间连边,但此时我们需要稍微修改一下连边方式,由于删除 \(x\) 会使得相邻点对被删除,所以我们对于一个相邻点对 \((y,z)\) 连边 \((y,x),(z,x)\) 即可。

此时由于我们要保留的是双连通性,所以当一个相邻点对被连边后我们不能立刻删除其,而是要当其被连了两次后再删除其,记一下次数即可,容易发现还是 \(O(n)\) 的。

对新图求割点即可做到 \(O(n \log n)\)。实际上如果考虑相邻点对,相邻二点对,相邻三点对后对每个点对加入三次之后就删除只做一侧,那么得到的图可以保留原图的点三连通性,可以求出该图的点三连通分量。