CF1034D Intervals of Intervals

\(n\) 个区间 \([a_i,b_i]\),定义区间的区间 \([l,r]\) 的价值是第 \(l\) 个区间到第 \(r\) 个区间的并的长度,找出 \(k\) 个不同的区间的区间,使得总价值最大。
\(n \le 3\times 10^5, 1 \le k \le \min\{\frac{n(n+1)}{2}, 10^9\}\)


  数据结构 扫描线 二分 双指针 set

  还是被 *3500 劝退了,然后发现其实是可做的。

  实际上这个题目非常套路。因为 \(k\) 很大,考虑如何二分出第 \(k\) 大的区间的价值。

  在二分的时候我们可以对 \(r\) 扫描线,对于所有 \(i\) 维护 \([i, r]\) 区间的价值之和,每次加入一个点 \(r\),我们可以直接在数轴上对于 \(r\) 的区间的点覆盖上其标号,然后 \([i, r]\) 的价值就是数轴上面所有标号 \(\ge i\) 的点的个数,因为值域比较大,可以使用 set 维护连续段,然后每次更新对于所有左端点价值的贡献都是形如 \([a,r]\) 的价值加上 \(v\) 的形式,可以直接差分处理。

  同时,因为 \(val([l, r]) \ge val([l + 1, r])\),于是在二分的时候,维护一个指针 \(p\),表示对于所有 \(l \in [1, p - 1]\)\(val([l, r]) \ge mid\) 的,于是就可以算出 \(\ge mid\) 的区间个数。

  最后我们可以二分出第 \(k\) 大的区间的权值 \(v\),然后我们的答案就是 \(f(v+ 1) +(k - g(v + 1)) v\) 了,其中 \(f(x)\) 表示 \(\ge x\) 的区间价值之和,这个求解部分和求个数差不多,讨论一下贡献就行了,可以看代码;而 \(g(x)\) 就是 \(\ge x\) 的区间个数。

  代码

posted @ 2022-04-05 20:27  Werner_Yin  阅读(47)  评论(0编辑  收藏  举报