Loading

9019 题解搬运


我们来讲讲怎么按题意模拟。

前置知识:超级钢琴,可持久化可并堆(左偏树)

我们有个朴素“暴力”:注意到若一个连通块在前 \(k\) 小中,则其所有子连通块一定也在。

于是我们钦定一个连通块是由根向插最小生成的。

具体的,初始连通块的根(\(1\) 根下深度最小的点)被生成,每次插入当前儿子邻域内在连通块内的最小值。(避免父子邻域交叉的混乱情况)

dij 那样每次拎出当前最小的,然后按上述尝试往外扩张,这时候用堆模拟能做到 \(O(kn+k\log n)\)

没有实现过,可能跑不满通过很多数据?


注意到浪费的时间在于扩张邻域每次 \(O(n)\),因为有一些扩张后我们可能用不上(不在前 \(k\) 小),就浪费了。

我们扩张顺序肯定是最小 \(\to\) 次小 \(\to\) 第三小 \(\cdots\) 这样精准扩张才能不造成浪费。

我们考虑对一个连通块,维护一个邻域堆,扩张的过程形如:每次先扩张最小值(然后邻域堆加入这个点的邻域),

删最小值,接着扩张,注意这时上个最小值其实不在此时扩张的连通块内。

然后在答案堆中维护当前连通块的权值和,扩张前的权值和,当前的邻域堆。

然后邻域堆要支持:可持久化合并,删最小值,查最小值,就是可持久化可并堆了。

代码很简短,不理解可以通过代码理解。

由于每个邻域只会被合并一次,复杂度 \(\mathcal{O}((n+k)\log n)\)

record

posted @ 2025-11-12 23:59  HaHeHyt  阅读(3)  评论(0)    收藏  举报