COCI 2021/2022 題解


看了下賽程,大概只能打 Round 1 和 Round 2 了,之后可能就退役了。

Contest #1

打的時候因為有點事,大概只打了一個多小時。現在終於有時間補完了。

題對於知識點完備的選手比較簡單。我顯然不是這樣的選手,做做就當學點東西了。

C、D、E 題代碼可以翻 LOJ,其他三題有需要可以聯系我。

A - Ljeto

直接模擬即可。

B - Kamenčići

博弈題。\(n\le 350\),比較小,可以考慮一個大概不超過 \(O(n^3)\) 的 dp。

考慮一個狀態有三個要素:左右端點和,以及共取了多少個紅色石子(只需要記錄一個人的,因為另一個以及可以據此確定)。

那么定義:\(f(l, r, c)\) 表示當前操作者面對的局面是,之前以及取過 \(c\) 個紅石子,現在剩下了區間 \([l,r]\),是否有必勝策略。

根據必勝必敗態定理得到轉移:\(f(l, r, c) = \lnot f(l+1,r, c') \lor \lnot f(l,r,c')\)\(c'\) 是計算得到的對方取過的紅石子數。

復雜度 \(O(n^3)\)。據說可以分析性質得到 \(O(n^2)\) 解法,可以到 cf 看看。

C - Logičari

第一次寫基環樹題!做法可能不是最簡潔的。

題意簡述:對基環樹黑白染色,要求每個點相鄰恰好一個黑點。求最小可能黑點數。

先轉化為正常的樹:任意找一條環邊 \((a, b)\) 斷開,然后欽定一下斷開的邊兩端的四種顏色組合。

不妨設 \(a\) 為根,每個點四個狀態,記錄自己和父親的顏色選擇。然后做正常的樹形 dp。

但是 \(a, b\)​ 兩個點需要是特殊處理的。對於 \(a\),可以試做它的父親為 \(b\)。而對於 \(b\) 需要額外討論一下……具體細節就不展開了。

復雜度 \(O(n)\)

D - Set

一下所有數字默認減一(\(\{1, 2, 3\}\to \{0, 1, 2\}\))。

我們挖掘一下題目的性質:對於一個位的三個數字 \((a,b,c)\),其所有合法組合對應的數字加起來都是三的倍數,即 \((a+b+c)\bmod 3 = 0\)

考慮到本質不同三元組個數為 \(3^m\)​,設 \(f[i]\) 表示 \(i\) 三進制表示對應的 \(m\) 元組的個數(\(f[i]\in \{0, 1\}\))。

題目要求選取的三個 \(m\) 元組 \(i,j,k\) 的每一位都滿足三進制不進位加法(\(\oplus_3\))為 \(0\),那么就是 \(i\oplus_3 j \oplus_3 k = 0\)

考慮卷積,下標用上面的 \(\oplus_3\),那么最后 \(f\) 自己卷自己三次后 \(f'[0]\) 就是答案。可以用 3 進制 FWT 實現。

E - Volontiranje

有一個傳統的流做法,但是應該只能跑 subtask 2。

考慮一個基於貪心的神奇結論:在所有備選 LIS 中,抽出一個反轉后字典序最小的必然不劣。

首先感性理解比較真,意識流 證一下也不難:考慮有兩組 LIS:\(\{i_1,i_2, \cdots,i_k\}, \{j_1,j_2, \cdots,j_k\}\)​​​​​​,那么我們對應項小的換到 \(i\)​​​​​​,大的換到 \(j\)​​​​​​,即用 \(\{\min(i_1, j_1),\min(i_2, j_2), \cdots,\min(i_k, j_k)\}, \{\max(i_1, j_1),\max(i_2, j_2), \cdots,\max(i_k, j_k)\}\)​​​​​​​ 取代之,不難發現其仍然合法。這個方法可以對一個解集在解之間做調整。但是如果最小的那個本身不被該解集包含,則我們可以不要這個解集,而必然存在另一個“可以向小調整”的解集。(看我題解很難沒有疑問(草),想要靠譜點的可以看 cf 或翻官方題解)

然后嘗試實現。直接一次 \(O(n)\)​​ 掃一組解必然不對,考慮先做一次 dp 跑出每個位置結尾的 LIS,然后按 dp 值將下標分組。顯然的,同一組的按位置升序排好之后,其值必然遞減。

那么,如果現在需要選 dp 值為 \(i\) 的組中的位置,上一次選了位置 \(x\)。我們先刪去在 \(x\)​ 之后的元素:易知這些元素在本次不可用,之后也不會起作用。

刪掉一些后,查看最后面的位置 \(y\) ,是否可以接上 \(x\)。如果 \(a_y > a_x\),那么 \(x\) 就沒辦法用了。需要注意,這不意味着求解結束,而只是將 \(x\) 刪去,\(y\) 可能在枚舉字典序更大的一組解是被使用。因此使用搜索回溯實現。

每個位置用一次就會被刪除,搜索部分復雜度 \(O(n)\)。總復雜度 \(O(n\log n)\)

Contest #2

A - Kaučuk

簽到

B - Kutije

首先轉化題意,將給定的 \(p_i\) 轉化為圖上的 \(i\to p_i\) 的有向邊。然后每個詢問相當於問是否存在 \(u\)\(v\) 的有向路徑。

觀察到 \(n\le 1000\),我們可以考慮預處理所有的答案。但這張圖是稠密圖,連做 \(n\) 次 DFS 的復雜度是 \(O(n^3)\)。不過我們發現一次 DFS 每個點之后訪問一次,但主要的時間消耗在於找到第一個沒有訪問過的相鄰點。

於是不難想到用 bitset 加速尋找,復雜度 \(O(n^3/w)\)

草,被自己蠢到了。考慮我們的圖是根據排列生成的,也就是若干個置換環疊合而成。那么很顯然對於一個連通塊(將所有邊取消方向),一定就是一個強連通分量。

於是直接對每個連通塊 DFS 即可,復雜度 \(O(n)\)

C - Hiperkocka

構造垃圾終於瞎搓成功了!

首先為了讓結構更清晰,我們將這些邊分為 \(n\)​ 層,根據第 \(k\)​ 位不同產生的邊放在第 \(k\) 層,每層有 \(2^{n-1}\)​ 條邊。

根據直覺,我們想辦法讓這 \(n\) 條邊的樹的每一條都用掉一層的一條邊,這樣恰好每層用 \(2^{n-1}\) 次。

第一棵樹是很好構造的,直接從位置 \(0\)​ 開始 DFS,每次 \(O(n)\) 遍歷最小未使用的層。然后我們發現如果從 \(1\) 直接開始 DFS 構造第二棵樹就可能沖突,不過根據觀察,我們要避開的話,最好是從 \(3\)​ 開始。

這時你可能發現了,位置 \(0\)\(3\) 除了上面幾層用的邊,其余都是對稱的。這啟發我們倍增地構造一組靠譜的起始點,使得直接在這些位置 DFS 就能出解(並不會證為什么可以這樣,這里如果有人會證可以發個評論)。

考慮從 \([0, 4)\to [4, 8)\)​,如果同樣用對應的位置 \(4,7\)​ 的話會沖突,而反過來用位置 \(5, 6\)​ 的話則恰好錯開,同時 \(5, 6\)​ 構造出的樹也是在低層對稱的,同 \(0,3\)​ 一樣也不會沖突。

那么不妨嘗試如下算法:初始區間 \([0,2)\)\(0\)​ 為起始點,然后復制一份,將是否為起始點狀態取反,接在后面。

然后對於每個起始點都搜出一棵即可。

D - Magneti

考慮一個確定的 \(n\) 個磁鐵的排列,設要使其不互相吸引的最小長度為 \(d\)(即盡量貼近),我們要將其放置在長度為 \(l\) 的槽中,根據插板法不難得到有 \({l-d+n \choose n}\) 種方法。

那么解題的方向就是,對於 \(d=1, 2, \cdots, l\) 分別計算對應的排列方案數,最后乘上組合數系數求和即為答案。官方解法給出了一個漂亮的動態規划方法:

首先將磁鐵按磁力半徑 \(r\) 升序排序,然后定義 \(dp(i, j, k)\) 表示放置前 \(i\) 個磁鐵,分為 \(j\) 組,每組的最小長度之和 \(=k\) 的方案數。這樣的好處是利用了升序排序后,只需要考慮當前的磁力范圍而不需要考慮之前的擺放。因此新的長度和 \(k'\) 可以很方便的計算,從而實現組之間的操作即,dp 的轉移:

  • \(i\) 個磁鐵單獨成為一個新的組:\(dp(i-1,j,k) \to dp(i,j+1, k+1)\)
  • \(i\) 個磁鐵貼在某個組的端點:\(dp(i-1,j,k)\times 2j \to dp(i, j, k+r_i)\)
  • \(i\) 個磁鐵連接了兩個組:\(dp(i-1,j,k)\times j(j-1) \to dp(i, j-1, k+(2r_i-1))\)

dp 部分復雜度為 \(O(n^2\times l)\)

這里的狀態設計的巧妙之處還在於分組思想:(摘自 CF)This idea is usually used when trying to construct permutations with certain properties.

E - Osumnjičeni

草,賽后發現是 sb 題,但是 C 題搞太久了……

考慮答案的計算方法是確定的:對於詢問 \([l,r]\),我們從 \(l\) 開始,找到一個最大的 \(i\le r\),滿足 \(l\sim i\) 號身高區間全部不交。那么下一次從 \(i+1\) 開始重復操作即可。最后答案就是操作的輪數(可能反過來再做一次)。

第一是預處理右側最遠的合法位置。考慮建立以身高(離散化)為下標的線段樹,從 \(1\) 掃到 \(n\)​。每次查詢當前身高區間中的最大值,然后在這個區間做區間賦值。最后做一遍后綴最小值。

第二是快速跳轉。不難發現這個可以倍增加速。

最后復雜度 \(O(n\log n)\)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM