Codeforces Round 954 (Div. 3)

A. X Axis

  • 给定 \(x_1, x_2, x_3\)。求 \(\min_i \sum_j |x_j-i|\)

显然排序后取中位数。

B. Matrix Stabilization

  • 给定 \(n \times m\) 的矩阵 \(a_{i,j}\)。每次操作找到一个 \(i\) 最小的前提下 \(j\) 最小的,满足 \(a_{i,j}\) 严格大于所有与它相邻的值的 \((i, j)\),并将 \(a_{i,j} \gets a_{i,j} - 1\)。输出不能操作时的矩阵。
  • \(n, m \le 100\)\(n \cdot m > 1\)\(1 \le a_{i,j} \le 10^9\)

说明:

  1. 以下分析复杂度时认为 \(n, m\) 同阶。
  2. 为方便表述,我们定义下标的不等关系为(其余不等关系 \(>, \le, \ge\) 的定义类比):

\[[(i_1, j_1) < (i_2, j_2)] = \left\{\begin{matrix} [i_1 < i_2] & i_1 \ne i_2\\ [j_1 < j_2] & i_1 = i_2\end{matrix}\right. \]

  1. 定义「操作 \((i, j)\)」为 \(a_{i,j} \gets a_{i,j} - 1\)
  2. \((i, j)\) 相邻的位置可能会有 \(1, 2, 3, 4\) 个。方便起见我们在 \(a\) 的上下左右分别用 \(0\) 填满。这样就一定是 \(4\) 个了。

暴力做法显然会爆炸。例如当 \(a = \begin{Bmatrix} 1 & 10^9 \end{Bmatrix}\) 时我们会将 \(a_{1,2}\) 操作 \(10^9\) 次。

进一步观察发现,如果 \((i, j)\) 是满足「大于所有与它相邻的值」的,那么接下来会「操作 \((i, j)\)」若干,直到 \(a_{i,j}\) 不满足「大于所有与它相邻的值」,也就是成为这些值中的最大值。

此时你就有了一个 \(\mathcal O(n^4)\) 的做法:执行至多 \(\mathcal O(n^2)\) 次,每次以 \(\mathcal O(n^2)\) 的复杂度找到这个 \((i, j)\),然后 \(\mathcal O(1)\) 修改。

这个时候就不得不讲个笑话了

考虑如何优化复杂度。如果我们称「『操作 \((i, j)\)』若干直到 \(a_{i,j}\) 不满足『大于所有与它相邻的值』」为一操作,事实上,如果这一操作 \((i, j)\),那么下一操作的 \((i', j')\) 一定满足 \((i, j) < (i', j')\)。换言之,你只需要从上一找到的 \((i, j)\) 开始往后找新一\((i', j')\) 即可。

考虑证明。

实际上我们需要证明两件事情:

  1. 如果 \((i, j)\) 是满足「大于所有与它相邻的值」的,那么接下来会「操作 \((i, j)\)」若干,直到 \(a_{i,j}\) 不满足「大于所有与它相邻的值」,也就是成为这些值中的最大值。
  2. 如果这一操作 \((i, j)\),那么下一操作的 \((i', j')\) 一定满足 \((i, j) < (i', j')\)

显然这两个命题可以合并成:

  1. 如果这一操作 \((i, j)\),那么下一操作的 \((i', j')\) 一定满足 \((i, j) \le (i', j')\)

考虑反证法。证明:

  1. 如果这一操作 \((i, j)\),那么下一操作的 \((i', j')\) 可能满足 \((i, j) > (i', j')\)

是伪的。

分类讨论。以下讨论的前提都是 \((i, j) > (i', j')\)

  • \((i', j'),(i, j)\) 相邻:那么操作 \((i', j')\) 后一定有 \(a_{i',j'} = \max(a_{i'-1,j'}, a_{i',j'-1}, a_{i', j'+1}, a_{i'+1,j}) \ge a_{i, j}\)。此时显然无法「操作 \((i, j)\)」,因为 \((i', j')\) 就是一个与 \((i,j )\) 相邻的且不大于 \(a_{i, j}\) 的位置。因此矛盾。
  • \((i', j'), (i, j)\) 不相邻:如果「操作 \((i, j)\)可以「操作 \((i', j')\)」,那么「操作 \((i, j)\)也一定可以「操作 \((i', j')\)」。所以上一步一定是「操作 \((i', j')\)」而不是「操作 \((i, j)\)」,这是因为 \((i', j') < (i, j)\)。因此矛盾。

综上,原命题得证。

C. Update Queries

  • 给定长度为 \(n\) 的字符串 \(s\) 和长度为 \(m\) 的数组 \(ind_i\) 和一个长度为 \(m\) 的字符串 \(c\)。你可以将 \(ind\)\(c\) 打乱顺序,然后依次按照 \(i = (1, 2, \dots, m)\) 执行 \(s_{ind_{i}} \gets c_i\)。求最后得到的字典序小的 \(s\)
  • \(n, m \le 10^5\)

显然贪心。发现 \(ind\) 中值 \(i\) 的出现次数是不重要的,我们只需要关注这个值是否出现。若 \(i\) 没出现那么一定仍保持 \(s_i\) 不变,否则一定是将 \(c\) 排序后,按 \(i, j\) 递增的顺序执行 \(s_i \gets c_j\)

D. Mathematical Problem

  • 给定一个长度为 \(n\) 的数字串。你需要在 \(n - 1\) 个空中选择 \(n - 2\) 个空插入运算符 \(+\)\(\times\)。求表达式的最小值。
  • \(t \le 10^4\)\(n \le 20\)

显然 \(\mathcal O(n)\) 枚举哪个空不放运算符。然后就可以得到总共的 \(n - 1\) 个数字。

显然 DP。设 \(f(i)\) 表示前 \(i\) 个数字构成的表达式的最小值。转移可以枚举 \(j\) 表示最后一个加号在 \([j - 1, j]\) 之间。即:

\[f(i) = \min_{j=1}^{i} (f_{j-1} + \prod_{k=j}^i a_k) \]

E. Beautiful Array

  • 给定长度为 \(n\) 的数组 \(a_i\) 和一个整数 \(k\)。你可以重新排列 \(a\) 使得将 \(a\) 成回文串的所需操作次数最少。定义一次操作为将任意 \(a_i \gets a_i + k\)
  • \(n \le 10^5\)\(k, a_i \le 10^9\)

考虑若只有两个数 \(x, y\),每次可以选择一个数将其加 \(k\),最少需要几步。

不难发现 \(x, y\) 加上无论多少倍的 \(k\) 后,在模 \(k\) 意义下的值一定是不变的。所以若最开始 \(x \not\equiv y \pmod y\) 那么无解。

否则,若 \(x \equiv y \pmod k\),此时最优方案一定是把 \(x, y\) 中的较小值累加到较大值。即最少需 \(\dfrac{|x-y|}k\) 步。

考虑 \(n\) 个数的情况。若 \(n\) 为偶数,那么我们相当于从中选出 \(\dfrac n2\) 对数,然后按照上面操作每对数。否则,若 \(n\) 为奇数,那么首先要选出一个数放在中间位置,剩下的 \(n - 1\) 个数按照偶数的操作。

先考虑偶数。我们可以统计出每个在模 \(k\) 意义下相同的数构成的集合,用 vector 存储。此时就可以对于每个 vector 单独考虑两两组对的情况(因为不同 vector 中的数 \(\bmod k\) 一定不同,根据前文所述一定不合法)。即:

给定一个数组 \(b_i\)。将这些数两两配对,使两个数的差的绝对值之和最小。

注意这里我们没有考虑 \(\dfrac 1k\) 的影响。因为我们只需要将这个公因式最后乘即可。

\(m = |b|\)。显然 \(m\) 为奇数时一定无解。否则一定是将 \(b\) 排序后相邻两个组成一对,即答案 \(\sum (-1)^ib_i\)

\(n\) 为奇数,那么我们需要找到一个长度为奇数的 vector,然后选择其中的一个放在 \(a\) 的最中间,然后剩下的按照偶数的处理。注意这里如果存在两个及以上长度为奇数的 vector 那么无解。现在的问题是:

给定一个长为奇数的数组 \(b_i\)。删除一个数后,将这些数两两配对,使两个数的差的绝对值之和最小。

若删除的数是 \(b_i\),那么此时的答案应为 \(\sum_{j=1}^i (-1)^jb_j + \sum_{j=i+1}^n (-1)^{j+1}b_j = \sum_{j=1}^i (-1)^jb_j - \sum_{j=i+1}^n (-1)^jb_j\)。预处理前后缀即可。

F. Non-academic Problem

  • 给定 \(n\) 个点 \(m\) 条边的简单无向连通图。你需要删除一条边使得图中连通的顶点对 \(1 \le u \le v \le n\) 最少。求这个最小值。
  • \(n, m \le 10^5\)

显然删除一个 e-dcc 中的点一定是不优的,因为这样不会连通的顶点对不会减少。

所以将 e-dcc 缩点,每个点的点权为其代表的 e-dcc 中的点数。因为原图连通所以形成了一颗树。我们考虑删除一条树边带来的收益。

若令这条边为 \((u, v)\),那么原本连通现在不连通的顶点对数,应该是从 \(u\) 出发不通过 \(v\) 能到达的节点数,与从 \(v\) 出发不通过 \(u\) 能到达的节点数的乘积。预处理子树和即可。

posted @ 2024-06-25 22:34  2huk  阅读(162)  评论(0编辑  收藏  举报