Loading

ABC469

A

减法。

code

B

模拟。

code

C

二分。

code

D

小分讨。

首先看第一局,\((a_1,b_1)\) 中必定有至少一个要被选中。那分讨选中第一个或者第二个,标记这个人覆盖的局数,然后寻找能把剩余的对局覆盖的选手的个数。

注意如果 \((a_1,b_1)\) 是合法解,那么会在前面的两遍计算中算重复,答案需要减 \(1\)。

code

E

二分答案双指针 check。

我们先二分一个答案 \(p\),再考虑如何检查其可行性。

一个区间 \([l,r]\) 是可行的当且仅当:

\[\begin{cases} \dfrac{\operatorname{cnt}_\mathtt{o}}{r-l+1} \ge p & \text{①} \\ r-l+1>k & \text{②} \end{cases} \]

利用 \(\operatorname{cnt}_\mathtt{o}+\operatorname{cnt}_\mathtt{x}=r-l+1\),可以化简 \(\text{①}\) 为:

\[(1-p)\operatorname{cnt}_\mathtt{o}-p \cdot \operatorname{cnt}_\mathtt{x} \ge 0 \]

我们可以将这个系数单独定义一个新数组 \(f\),字符串中为 \(\mathtt{o}\) 的下标赋值为 \((1-p)\),为 \(\mathtt{x}\) 的下标赋值为 \(-p\)。这样 \(\text{①}\) 式等价于 \(f\) 在 \([l,r]\) 的子段和非负,这可以预处理 \(f\) 数组的前缀和实现。

保证 \(\text{②}\) 式成立可以使用双指针。对固定的 \(r\) 存在最大的 \(l_{\max}\) 满足 \(\text{②}\)。此时每个 \(l \le l_{\max}\) 均能满足 \(\text{②}\)。

由于需要找到以 \(r\) 为右端点的子段区间和的最大值,只需要找到前缀和最小的左端点,可以预处理前缀最小值。注意由于可能 \(l=1\),此时用到的前缀和为 \(s_0=0\),所以前缀最小值永远是非正的。

时间复杂度 \(O(n \log n)\)。

code

F

更换枚举方式。

边数是 \(O(n^2)\),普通的 prim 和 kruskal 都不行。

注意到值域是 \(10^6\),这里我们从大到小枚举最大公因数 \(g\),寻找每一个它的倍数。此时这些倍数组成的集合可以用权值为 \(g\) 的边联通。由于从大到小枚举,这样贪心地做和 kruskal 很像,正确性可以保证。

循环次数 \(\frac{V}{1}+\frac{V}{2}+\dots+\frac{V}{V}\),为 \(O(V\log V)\) 级别。

code

G

矩阵递推,不写了。

posted @ 2026-08-15 12:10  tai_chi  阅读(10)  评论(0)    收藏  举报