CF2018E2 Solution

CF2018E2 Solution

先考虑E1的做法。

首先我们如果钦定一组 k 条线段的话,容易求出最大组数。

简单来讲就是将所有端点按照右端点排序,这样只需要考虑一个偏序,然后扫描,将区间 [li,ri] 加一,当发现某个点的值为 k 时,就说明分成了一组方案。

此时我们一定清空,然后记录当前的 r,也就是后面选的点左端点不得小于等于 r

直觉上,这样贪心选择一定更优。设这样的答案为 k

我们的答案可以表示为 maxk·f(k)

而我们发现,对于一个固定的 f(k),它是随着 k 单调不升的,这很显然。

所以对于一个固定的 f(k),可以通过二分的形式得到 maxk,这样就足以在 O(nlognnlogn) 解决问题,足以通过 E1。

事实上在这里可以通过整体二分求得所有的 f(k),它的复杂度足以降至 O(n1.5logn),这是因为在第 d 层时,值域被划分为了 O(n2d) 长的 2d 段,在 [n2d/2,n] 范围内 f2d/2,而 [1,n2d/2] 又仅有 O(2d/2) 段,所以这里总段数是 O(2d/2) 的,总的整体二分复杂度就是 O(log2n2d/2)=O(n) 的。

那么考虑优化线段树这个过程,一个很重要的技巧是,我们只关心全局最大值,以及后缀加

那么可以使用并查集,维护后缀最大值出现位置

首先,我们使端点互不相同,具体地,将原本的所有端点排序(如果是相同值,原本为右端点的放在后面),然后依次给其赋值 12n

这显然不会破坏相交关系也不会新增。

然后我们利用并查集维护差分,每次后缀加只会造成新的 r 成为一个后缀最大值,以及增加的最大的 <l 的后缀最大值端点删去。

利用并查集维护这个即可。

posted @   spdarkle  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示