序列合并 Trick
可能其他人觉得很简单,但是我觉得还是比较巧妙的。
就是如何在接受复杂度内合并两个序列和的信息并且保留前 \(k\) 小。
我们肯定先把两个序列 \(a, b\) 排序。
然后我们固定一个 \(i\),如果此时暴力枚举到的 \(j\) 满足 \(a_i + b_j\) 可以替换掉目前维护的前 \(k\) 小中最大的,那么就直接替换掉,否则直接跳出 \(j\) 的循环,因为此时 \(b\) 是排过序的,所以 \(a_i + b_j\) 加不进去,那么 \(a_i + b_{j + 1}\) 必然加入不进去。
这看似是一个很简单的暴力优化,实则复杂度是对的!!!
因为我们发现 \(\le a_i + b_j\) 的数一定有 \(i \times j - 1\) 个,然后证明了对于一个 \(i\),最多到 \(\frac{k}{i}\) 就会直接跳掉,我们发现这个东西复杂度是一个调和级数级别的东西,所以算上数据结构维护的复杂度就是双 \(\log\) 的了。
然后是一个不是那么有用的 Trick 维护多序列合并,也就是 \(\sum len_i \le n\),然后要求维护前 \(m\) 大:


浙公网安备 33010602011771号