1. 程式人生 > 實用技巧 >CF1451(Div.2)題解

CF1451(Div.2)題解

A. Subtract or Divide

顯然,對於一個偶數,我們可以將其通過一次操作變成 \(2\)。奇數可以通過一次操作變成偶數,再通過一次操作變成 \(2\)。所以偶數的答案是 \(2\),奇數的答案是 \(3\)。注意特判 \(1\) 的答案是 \(0\)\(2\) 的答案是 \(1\)\(3\) 的答案是 \(2\)

B. Non-Substring Subsequence

因為這道題對時間限制比較鬆,\(O(n^2mq)\) 的演算法也是可以接受的。考慮暴力列舉整個 \(01\) 串禁止轉移的點(顯然不包括 \(1\)\(n\)),分兩部分對詢問的 \(01\) 串進行匹配,這樣可以保證分割出來的方案不相鄰。又考慮到遍歷匹配可能出現一邊直接匹配了整個字串,所以我們還需要對詢問串進行分割,將一半放在左邊匹配,一半放在另一邊匹配。這樣就能通過了。

C. String Equality

因為操作可以做無限次,所以說整個字串可以重排。所以字串的順序並不重要。通過第二個操作看,實際上重要的是每個字元的個數。

顯然,出現了相同的字元,我們直接匹配,相當於減少兩個串中這個字元減少出現次數就行了。因為這個相同的字元如果不匹配,就一定會變成更大的字元,永遠不能夠匹配這個字元了。

於是,如果字元個數相同,匹配;否則將能匹配的匹配了,然後轉移給下一個字元。注意到有 \(k\) 的限制,注意下轉移時判斷一下是否是 \(k\) 的倍數。桶排瞎貪心即可。

D. Circle Gam

這種題第一步就是手模擬。不如嘗試一下?

我們發現,設 \(x=\dfrac{d}{k}\)

,當:

  • \(x<\sqrt{1^2+0^2}\) 時,先手必敗;
  • \(\sqrt{1^2+0^2} \leq x < \sqrt{1^2+1^2}\) 時,先手必勝;
  • \(\sqrt{1^2+1^2} \leq x < \sqrt{1^2+2^2}\) 時,先手必敗;
  • ……

顯然這是有規律的。對映到遊戲來,會發生什麼?

注意到根號內的第二個數(沒有平方)是最優情況下先手可以走的步數,第一個數同理是後手可以走的步數。

於是可以猜測,先手一直往上,後手一直往右一定是整個遊戲的最優狀態。如果先手必勝,當後手往上的時候,先手可以往右調整這個狀態,後手仍然是必敗態;當先手是必敗態的時候,後手可以同樣用這個方法去調整狀態。

綜上完事兒。少用 sqrt()

E1. Bitwise Queries (Easy Version)

這是一個沒有用到任何性質的題解。

首先給出一個式子:

\[a \operatorname{xor} b + 2 \times (a \operatorname{and} b) = a+b \]

考慮證明:\(a \operatorname{xor} b\) 部分等於 \(a,b\) 不相同的位減去 \(a,b\) 都是 \(1\) 的位。所以需要兩個 \(+a \operatorname{and} b\) 去調整得到 \(a+b\)

對前面三個查詢 \(5\) 次,分別是 \(a_1 \operatorname{xor} a_2,a_1 \operatorname{xor} a_3,a_1 \operatorname{and} a_2,a_1 \operatorname{and} a_3,a_2 \operatorname{and} a_3\)\(a_2 \operatorname{xor} a_3\) 可以通過前兩次查詢結果異或得出),這樣就能知道 \(a_1+a_2,a_1+a_3,a_2+a_3\)

聯立解方程可以得出 \(a_1,a_2,a_3\)。然後再根據異或的性質,知道一個數,兩個數異或的結果,得到另一個數。每次查詢一遍即可。查詢次數 \(5+n-3=n+2\)

注意不要把陣列開小了。

E2. Bitwise Queries (Hard Version)

請丟掉 E1 的做法。我們發現我們完全沒有用 \(n\)\(2\) 的冪次,值域在 \([0,n-1]\) 的訊息。

首先注意到數的數量是 \(n\),值域大小也是 \(n\)。所以說這個序列要麼有重複元素,要麼是一個 \(0 \sim n-1\) 的排列。

首先求 \(1\) 對其他數的 \(\operatorname{xor}\) 值無可避免。於是先求出來。

發現如果整個序列有相同的值,顯然有一個數對 \((x,y)\) 滿足兩個數與 \(a_1\) 異或值相等。隨便找一找,如果存在這個數對,我們就能通過一次 \(\operatorname{and}\) 或者 \(\operatorname{or}\) 操作求出 \(a_x,a_y\)。然後反代回去求出整個序列。操作次數 \(n\)

順便注意一下有沒有一個數滿足這個數與 \(a_1\) 異或值為 \(0\)。同樣的做法求一發 \(a_1\) 即可。

重要的是這個排列怎麼求。實際上也很簡單。因為這是一個排列,所以說一定存在兩個數 \(x,y\),使得 \(a_1 \operatorname{xor} a_x = n-1,a_1 \operatorname{xor} a_y = 1\)

考慮這樣個玩意兒的意義。首先第二個式子可以發現,\(a_1,a_y\) 一定只相差 \(1\)。進行一個 \(\operatorname{and}\) 操作可以知道 \(a_1\) 除奇偶性的所有前面的資訊。

兩個式子連起來一看,發現 \(a_x\)\(a_y\) 的奇偶性一定相同。所以我們也能知道 \(a_1\) 的奇偶性。具體就詢問 \(a_x \operatorname{and} a_y\),其奇偶性與 \(a_1\) 不同。綜上,操作次數 \(n+1\)

至此,我們解決了這道題。

F. Nullify The Matrix

咕一發。以後更。