Loading

数学的神奇推导

ARC 167 C - MST on Line++

根据思路的不同有两种截然不同的做法,一种只能优化到 \(O(n^2)\),而另一种可以优化到 \(O(n)\)。所以适当改变思路很重要吧?

我的思路是考虑求 \(\text{MST}\) 的过程,我们从按边权小到大枚举每一条边,统计每一种点权的贡献。考虑边权是 \(max(a_i,a_j)\)。一个常见的套路是从按点权小到大枚举,设当前的点为 \(i\),它是第 \(j\) 小,那么就只需要考虑 \(i\) 和之前的点的之间的边。我们发现有三种情况:

  1. \(i\) 左边和右边的第一个点和 \(i\) 的距离都 \(>k\),这时不会有贡献。
  2. \(i\) 左边和右边的第一个点和 \(i\) 的距离都 $ \leq k$,并且这两个点的距离 \(>k\),这时会有 \(a_i \times 2\) 的贡献。
  3. 否则就会有 \(a_i\) 的贡献。

暴力求这个是 \(O(n^3)\) 的,最后写出来是类似于 \(\sum_{i=l}^r \binom {i} {n}\) 的形式,就可以 \(O(n^2)\) 求了。

这个做法过于朴素了,而且还要枚举每一个位置和权值,不太行。

考虑计算 \(\text{MST}\) 中边权 \(\leq i\) (排名 \(\leq i\)) 的边的数量 \(f_i\) ,答案即为 \(\sum (f_i-f_{i-1}) \times a_i\)

计算 \(f_i\) 就要好很多了,因为只需要考虑所有权值 \(\leq\) 的点之间连了几条边。也就是求 \(n\) 个点中选 \(i\) 个点求相邻两个点距离 \(\leq k\) 的数量之和。这个问题看似不太能快速求解,但可以考虑组合意义:我们计算第 \(j\) 和第 \(j+1\) 的距离 \(> k\) 时方案数就是 \(\binom {n-k} {i}\),这样就可以建立一个双射。所以可以做到 \(O(n)\)

总结:最小生成树的性质可以让我们快速求出 \(f_i\),对于距离 \(>k\)\(=k\) 的问题可以先将总数减去 \(k\) 再求解。

posted @ 2023-10-19 21:16  Bobby7000  阅读(60)  评论(0)    收藏  举报