Codeforces Round 954 (Div. 3)

2huk發表於2024-06-25

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\)

F. Non-academic Problem

  • 給定 \(n\) 個點 \(m\) 條邊的簡單無向連通圖。你需要刪除一條邊使得圖中連通的頂點對 \(1 \le u \le v \le n\) 最少。求這個最小值。
  • \(n, m \le 10^5\)

相關文章