题解:CF1034D Intervals of Intervals

题意:给你若干个区间 \([l_1,r_1]...[l_n, r_n]\),定义 \(f([L,R]) = \bigcap\limits_{i=L}^{R}[l_i,r_i]\),求前 \(k\) 大的权值之和。

做法:

首先看到前 \(k\) 大,那么很自然想到我们去二分最小的权值 \(x\) 是多少,然后去枚举右端点,同时维护左端点的最大值,计算出总共有多少个点对的权值至少为 \(x\)。当我们知道最小的权值为 \(V\),我们再算出来权值 \(\ge V + 1\) 的点对权值之和再加上 \(=V\) 的权值贡献。

那么我们现在只需要解决两个问题:

  1. 如何求解有多少个点对,他们的权值都 \(\ge x\)

  2. 如何求解对于权值 \(\ge x\) 的点对,他们的权值之和是多少。

第一个可以很容易通过双指针 + 线段树解决,这里简单讲一下,我们类似扫描线,每个节点维护一个覆盖标记和覆盖的区间长度,然后按照扫描线的方法类似维护即可,加上外层的二分是 \(O(n\log^2 n)\) 的,可以自己写写,我是被卡常了

那么怎么样去做到 \(O(n)\) 呢,我们换一种统计的思路,仍然采用双指针。在右指针从左往右扫的时候,我们考虑给每个数轴上每个点 \(p\) 记录一个 \(last\) 数组,代表他最后一次被第 \(last_p\) 个区间给覆盖了,有点类似数颜色数通过数最后一个去重的手法。

那么我们现在需要检验点对 \((l', r')\) 是否可行,就等同于要求 \(\sum\limits_p [last_p \ge l']\) 的个数是否 \(\ge x\)。而维护这个 \(last\) 数组我们可以直接用珂朵莉树维护,所以这样做均摊下来复杂度是 \(O(n\log n)\) 的。

你可能会觉得这样并没有什么用,加上二分仍然是 \(O(n\log^2 n)\) 的,但是注意到一个事情,我们这里每次覆盖的区间其实是确定的,所以就意味着我们没有必要每次二分时重新用 set 维护颜色段,可以在二分之前提前预处理出来,复杂度就是 \(O(n\log n)\) 的了。


我们现在考虑第二个怎么做。

我们先将问题弱化一下,考虑没有那么多点对,而是 \(O(n)\) 个点对怎么做。

我们同样类似第一个问题中后面提到的方法,我们先进行扫描线,枚举右端点,同时维护以 \(x\) 为左端点的点对的答案。

考虑一个点对答案的贡献。一个点 \(x\) 的标记从 \(l\) 变成 \(l'\) 的时候,左端点在 \((l',l]\) 内的点对都会获得 \(1\) 的贡献。我们可以用线段树维护这个修改即可,对于查询一个点对的时候,直接在线段树上单点查就可以了。

那么对于原问题,对于一个右端点,我们的左端点是一个区间,那么我们就在线段树上区间查就可以了。

总复杂度 \(O(n\log n)\)

posted @ 2025-07-11 21:56  LUlululu1616  阅读(13)  评论(0)    收藏  举报