0%

The 6th Liaoning Provincial Collegiate Programming Contest-2025-辽宁省赛-M. Many CF Rounds vs Capoo 猫猫虫打 CF(这种有一个元素有两个值的这种东西,可以把他们看作是一条线段,画在这个数轴上面,兴许可以看出些什么,至少比干瞪眼好)

题目大意

题目描述
Capoo 的初始 rating 为 x=0x=0
现在有 nn 场比赛,对于第 ii 场比赛,它的难度为 aia_i,隐藏分数为 bib_i。每场比赛最多只能参加一次。
只有当当前 rating xaix \le a_i 时,Capoo 才能参加第 ii 场比赛。参加完该场比赛后,Capoo 的 rating 将会更新为 max(bi,x)\max(b_i, x)
你可以自由安排参加这 nn 场比赛的顺序,求 Capoo 最多能参加多少场比赛。

输入格式
第一行包含一个整数 nn1n1061 \le n \le 10^6)。
接下来的 nn 行,每行包含两个整数 aia_ibib_i0ai,bi10180 \le a_i, b_i \le 10^{18}),分别表示第 ii 场比赛的难度和隐藏分数。

输出格式
输出一行一个整数,表示 Capoo 最多能参加的比赛场数。

样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
输入:
10
19 18
6 15
5 8
4 20
18 3
16 9
0 7
5 17
2 13
15 17

输出:
5

样例解释

注意,这个人比较喜欢挑战这个难题。
一种最多参加 55 场比赛的合法顺序如下:

  1. 初始时 x=0x = 0

  2. 参加第 77 场比赛(a7=0,b7=7a_7=0, b_7=7):满足 xa7x \le a_7000 \le 0),参加后 xx 更新为 max(0,7)=7\max(0, 7) = 7

  3. 参加第 55 场比赛(a5=18,b5=3a_5=18, b_5=3):满足 xa5x \le a_57187 \le 18),参加后 xx 更新为 max(7,3)=7\max(7, 3) = 7

  4. 参加第 66 场比赛(a6=16,b6=9a_6=16, b_6=9):满足 xa6x \le a_67167 \le 16),参加后 xx 更新为 max(7,9)=9\max(7, 9) = 9

  5. 参加第 1010 场比赛(a10=15,b10=17a_{10}=15, b_{10}=17):满足 xa10x \le a_{10}9159 \le 15),参加后 xx 更新为 max(9,17)=17\max(9, 17) = 17

  6. 参加第 11 场比赛(a1=19,b1=18a_1=19, b_1=18):满足 xa1x \le a_1171917 \le 19),参加后 xx 更新为 max(17,18)=18\max(17, 18) = 18
    总计参加了 55 场比赛,可以证明这是最多能参加的比赛场数。

思路讲解

将所有比赛分成两组:

  • 安全组 Abiaib_i \le a_i。参加后 xmax(x,bi)aix \leftarrow \max(x, b_i) \le a_i,也就是说参加这场比赛不会把 xx 抬到超过它自身的门槛 aia_i。对后续的影响很温和。

  • 危险组 Bbi>aib_i > a_i。参加后 xx 必然跳到 bib_i(因为 bi>aixb_i > a_i \ge x),对后续影响大。

为什么这个分组有用?因为安全组内部,如果按 aia_i 升序排列,全部都能参加——每次参加后 xaix \le a_i,而下一场的 aa 更大,必然满足条件。所以安全组是"稳赚不赔"的。

下一步应该关注:安全组全做了,危险组怎么尽可能多地塞进来**?(把安全组给固定住)**

image

第三层:排序与交错——两组的最优合并策略

  • 安全组按 aia_i 升序排。

  • 危险组按 bib_i 升序排(参加后 xx 跳到 bib_i,越小越好,留给后面的空间越大)。

一下的这个规则就是,在上面情况下,B 不会影响 A?(先不要去想 B 会不会生效

关键的交错规则:在做每一个危险组比赛 BjB_jbb 值为 bjb_j)之前,先把安全组中所有 ai<bja_i < b_j 的比赛做完。

为什么?做完 BjB_jx=bjx = b_j,那些 a<bja < b_j 的安全组比赛就再也做不了了。提前做掉它们不会抬高 xx(因为安全组的 ba<bjb \le a < b_j),不影响 BjB_j 的可行性。

这样,安全组的比赛一场都不会浪费——它们总是在 xx 被抬高之前被消化掉。最终的答案就是:

安全组全部+按上述交错策略能做的危险组数量\text{安全组全部} + \text{按上述交错策略能做的危险组数量}

不难想到,危险组按照这个 b 从小到大排比较好,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
auto forward=[&]() -> bool {
while (idx1<SZ(safeA) && idx2<SZ(dangerA) && safeA[idx1].a<dangerA[idx2].b) {
cur_ability=max(cur_ability,safeA[idx1].b);
++idx1;
}

if (cur_ability<=dangerA[idx2].a) {
cur_ability=max(cur_ability,dangerA[idx2].b);
++ans;
}
++idx2;
if (idx2<SZ(dangerA)) {
return true;
}
return false;
};
while (forward()) {
}

AC代码

心路历程(WA,TLE,MLE……)