場上題目看錯兩次,day2 成功爆炸 /ll
為什么我總是拿不到自己該拿的分呢?
本文下標從 1 開始
算法 1
我會容斥!
先把問題轉化成統計不存在一個合法位置的方案數。
接着統計有欽定 \(k\) 個合法的,其他隨便的方案數。其容斥系數為 \((-1)^k\)。
在一次機器人的操作后,所有輸入的數在經過機器人在操作后的輸出都可以表示成 \(0\),\(1\),\(x\) 或 \(1-x\) 的形式(\(x\) 是這個位置上輸入的數)
考慮一個紙帶:對於一個被欽定的每一個位置,要求輸入經過這個機器人操作之后一定等於輸出。仍然把輸出表示成輸入的形式,只不過這個輸出可以以多種方式被輸入表達。
對於每一個位置分類討論:
- 如果這個位置上表示成的結果
既有 0 又有 1
或既有 x 又有 1-x
:輸入輸出都為空。方案數為 1。 - 如果不滿足條件 \(1\),這個位置上表示成的結果
有 0 或 1
且有 x 或 1-x
:輸入輸出都為空,否則輸入輸出就被固定了。方案數為 2。 - 條件 1,2 都不滿足:對於每一個輸入都對應一個唯一的輸出,方案數為 3。
這個紙帶上每一個位置就是獨立的了,最后把每個位置的答案乘起來即可。
注意機器人爆炸的情況。
時間復雜度 \(\Theta(n^22^nm)\),期望得分 \(20\)。
算法 2
我會優化算法 1!
對於第 \(i\) 個機器人,考慮實際進行修改了的位置只有 R
的個數個(設為 \(c_i\))。
考慮枚舉最后一個欽定的位置在哪里(設為 \(r\))。這樣就可以知道哪些機器人是爆炸的了:有且僅有 \(c_i > n - r\) 的爆炸了。
然后對於前 \(r\) 個位置 \(\rm DP\)。狀壓記錄前面的元素中哪些元素被欽定了。欽定了一個位置就給答案乘上 \(-1\)。在 \(\rm DP\) 的過程中,做到第 \(i\) 個數就把第 \(i\) 個位置的貢獻(即輸入輸出方案數)統計掉。
但我們發現並不是所有元素都需要記錄下來的:只用記錄與當前位置距離不超過 \(n - r\) 的和與當前位置距離超過 \(n-r\) 的位置中有沒有 \(1\) 即可。
最后再處理一下位置超過 \(r\) 的元素即可。
時間復雜度 \(\Theta(n^2m2^{n/2})\),期望得分 \(48\)。
算法 3
我會 bitset!
發現我們統計一個位置的貢獻的時候,只有 是否有...
有用。所以考慮用 \(\rm bitset\) 同時處理一堆紙條是否有 0,1,x 和 1-x
。
這樣復雜度就降到了 \(\Theta(\frac{n^2m2^{n/2}}{\omega})\),常數巨大。但是還可以優化。
其實我們要求的是類似於一個子集中的 \(\rm bitset\) 的子集並,這個東西仍然可以優化,就是類似於 f[x] = f[x & -x] | f[x ^ (x & -x)]
。
時間復雜度 \(\Theta(\frac{nm2^{n/2}}{\omega})\),期望得分 \(100\)。
感覺講的有些抽象,不過相信大家想到算法2 之后就會做了。
算法 4
考慮換個維度思考,對於每一個紙條,考慮他對哪些集合的貢獻是 \(1\),哪些集合的貢獻是 \(3\),算出來這兩個就可以算出哪些集合貢獻為 \(2\)。
問題基本轉化成了這樣:\(n\) 個元素被划分為 \(4\) 個集合 \(S_0,S_1,S_2,S_3\),要將滿足 [有 \(S_0\) 和 \(S_1\) 中的元素] 或 [有 \(S_2\) 和 \(S_3\) 中的元素] 的集合權值 +1,最后求每一個集合的權值和。這個東西可以用容斥解決(轉換成多個對 \(T_i\) 的所有子集 \(S\) 權值增加 \(W_i\))
感覺我講不太清楚。。。。。
時間復雜度 \(\Theta(n^2 (m + 2^{n / 2}))\)。期望得分 \(100\)。
祝大家學習愉快!