2025 四川省赛部分题题解

K. 点分治

我们倒着考虑 \(p\) 序列, 也可以看做将每个点依次加入进图里.

假设当前加入的点为 \(u\), 我们遍历其所有出边到达的点 \(v\), 如果 \(v\) 被访问过, 那么就将 \(v\) 所在连通块内「在 \(p\) 序列中最早出现」的点的父亲设为 \(u\), 正确性显然.

实现采用并查集, 每次 \(\rm{merge}\) 操作将 \(u\) 设为连通块的根即可, 复杂度 \(\mathcal{O}(n \log n)\).

C. 最优时间

我们可以先在 \(\mathcal{O}(n \ln n)\) 的复杂度内处理出所有 \(|S(x)|\)​ 的值.

对于期望的题, 我们通常是倒着做, 但对于这道题而言十分困难, 因此我们考虑「迭代」做法.

定义 \(f_x^{(k)}\) 表示迭代 \(k\) 次后 \(f_x\) 的值, 暴力迭代可得

\[f_x^{(k + 1)} = \min(f_{x - 1}^{(k)}, \frac{\sum_{y \in S_x} f_{y - 1}^{(k)}}{|S_x|}) + 1 \]

初始 \(f_x^{(0)} = x\). 最终答案即为 \(f_x^{(\infin)}\). 官方题解证明了这个式子是收敛的, 大概迭代 \(100\) 次即可满足题目要求, 复杂度 \(\mathcal{O}(k n \ln n + q)\), 其中 \(k = 100\).

L. abc

先考虑一下字符集大小为 \(2\) 时的做法. 套路的, 将一个字符的权值设为 \(1\), 另一种字符的权值设为 \(-1\), 记前缀和数组为 \(s\), 那么最终答案即为 \(\displaystyle \sum_{1 \le i < j \le n} |s_i - s_j|\) 吗? 对于只有单个字符的区间实际权值为 \(0\), 我们需要在上式的基础上减去多余的权值.

对于字符集大小为 \(3\) 的情况, 有一个 key observation:

\[\max(|a - b|, |b - c|, |a - c|) = \frac{|a - b| + |b - c| + |a - c|} 2 \]

有了这个观察, 我们就可以类比字符集大小为 \(2\) 的情况, 对于任意 \(2\) 个字符求出权值并相加除以 \(2\) 即可.

当然, 这只对于 \(3\) 种字符均出现的区间是正确的, 而对于只出现了 \(2\)\(1\) 种字符的区间, 我们需要减去多余的权值. 对于只出现了 \(1\) 种字符的区间多余的贡献只好算的, 接下来我们讨论出现仅 \(2\) 种字符的区间.

定义 \(c_{a/b/c}\) 表示 \(a/b/c\) 在该区间内的出现次数. 首先钦定两个字符 \((\)假设为 \(a, b)\), 采用上述式子计算的贡献为

\[\frac{|c_a - c_b| + |c_a - 0| + |c_b - 0|} 2 = \frac{|c_a - c_b| + c_a + c_b} 2 \]

而该区间应该的贡献为 \(|c_a - c_b|\), 两式相减, 可得多余的贡献

\[\frac{|c_a - c_b| + c_a + c_b} 2 - |c_a - c_b| = \frac{c_a + c_b - |c_a - c_b|} 2 = \min(c_a, c_b) \]

总的多余的贡献也即 \(\displaystyle \sum_{\text{只出现的 2 种字符的区间}} \text{出现次数较少的字符出现次数}\).

根据字符集大小为 \(2\) 的做法, 计算出的答案为 \(\sum(\max - \min)\), 同时注意到 \(\sum(\max + \min)\) 就是区间长度, 作差即为 \(\sum \min\).

对于 \(\displaystyle \sum_{1 \le i < j \le n} |s_i - s_j|\), 注意到 \(0 \le s_i \le 10^6\), 采用桶排序做前缀和可以做到线性复杂度.

posted @ 2025-06-18 16:12  Steven1013  阅读(244)  评论(0)    收藏  举报