题解:P14593 [LNCPC 2025] 猫猫虫打 CF
Brilliance_Z · · 题解
这是本题的官方题解。
把比赛
- 上升类:
a_i < b_i 。 - 下降类:
a_i \ge b_i 。
:::info[性质 1]{open}
如果所有的比赛都是下降类,那么显然所有的比赛都能够参加。
:::
下面考虑同时有上升类和下降类的情况。
:::info[性质 2]{open}
一场上升类
其他情况都可以通过一些策略做到能够参加这两场上升类和下降类。
:::
可以通过分类讨论证明。
下面介绍两种解法和一种在这些解法的基础上更简单的代码写法,时间复杂度都是
解法一
答案可写成:
其中
求解答案等价于在上升类上做带权区间调度:每个上升类
关键在于高效计算每个
- 把所有下降类
(a_i,b_i) 按a_i 升序排序,维护一个按b_i 的树状数组。 - 按上升类的
b_i 升序遍历到当前b_i 时,把所有满足a_j < b_i 的下降类(a_j,b_j) 加入树状数组(在其b_j 处+1 )。 - 此时,
c_i = \text{已加入个数} - \text{BIT.prefix}(a_i) 即"
a_j < b_i 并且b_j > a_i "的个数(严格包含,端点相等不算)。
随后在上升类中做标准的带权区间调度 DP:
- 将上升类
(a_i,b_i) 对应的上升区间[a_i,b_i] 按b_i 升序排序,预处理每个区间的前驱p_i (使得b_{p_i} \leq a_i 并且p_i 最大)。 - 状态转移方程:
\text{dp}_i = \max (\text{dp}_{i - 1}, \text{dp}_{p_i} + w_i)
解法二
:::info[性质 3]{open}
当一场上升类和一场下降类冲突时,参加上升类会导致猫猫虫的能力值变得更大,是不优的。
:::
因此,应当舍弃所有满足“存在一个下降类
- 关于舍弃,可以把上升类
(a_1,b_1) 看作区间[a_1,b_1] ,把下降类(a_2,b_2) 看作区间[b_2,a_2] 。 - 将所有区间按照右端点从小到大排序,当两个区间的右端点相同时,上升类区间排在下降类区间的前面。
- 排序后扫描所有区间,并维护当前扫描过的下降类区间的左端点的最大值
l_{max} 。 - 如果扫描到一个上升类区间的左端点小于
l_{max} ,那么应当舍弃它。
舍弃完后,显然所有的下降类都是能够参加的。
因此可以不管下降类,只用考虑剩下没被舍弃的上升类。
剩下没被舍弃的上升类最多能参加多少场,等价于最多不相交(不含端点)区间数量,这是一个经典的贪心区间问题:
- 将这些区间按照右端点从小到大排序。
- 排序后扫描这些区间:如果当前区间是第一个区间或者和上一个选择的区间不相交,那么选择该区间;否则,跳过该区间。
一种更简单的代码写法
在前面解法的基础上,有一种更简单的代码写法:将所有比赛按照
可以发现这种写法和前面两种解法是等价的。