1. 程式人生 > 其它 >NOIP2020 部分簡要題解

NOIP2020 部分簡要題解

現在還是不會啊 qwq

C

首先考慮 \(n = 2\) 怎麼做。

可以發現的是我們一定要藉助空柱子 \(n + 1\),並且兩個柱子都必須要移動。

注意到此時本質上就是將兩種球分類,於是我們考慮能否將一個柱子上兩種顏色分開(並對其他柱子不產生影響)。

假設要將 \(1\) 上兩種顏色分開,並且 \(1\) 顏色在上 \(2\) 在下。

\(1\) 柱子上有 \(a\)\(1\) 那麼我們考慮現在第 \(2\) 個柱子上先預留 \(a\) 個空位,將這些球先全部轉移到 \(n + 1\) 上。

然後對於第一個柱子上的球從上到下考慮,若當前頂端的球為 \(1\) 則放到 \(2\) 柱子上,否則放到 \(n + 1\)

上。

然後先將 \(n + 1\) 上方的 \(m - a\)\(2\) 球還原到 \(1\) 柱子,再將 \(2\) 上方的 \(a\)\(1\) 球還原到 \(1\) 柱子,最後將 \(n + 1\) 剩下的球還原到 \(2\) 柱子。

容易發現這樣對 \(2\) 柱子沒有影響且操作合法達成了目的,仔細定量發現運算元是 \(2m + 2a\) 的。

我們對兩個柱子都做上面的操作將 \(1\) 放到上面來,然後就可以輕鬆達成目標了。

接下來回到原問題,此時我們發現上述做法的本質是:將柱子 \(x\) 上顏色為 \(c\) 的球上提到頂端且 \(x\) 上其他球相對位置不變,同時不會對其他柱子產生影響。

此時考慮按照顏色依次還原,假設當前考慮到了顏色 \(c\) 對上述柱子將 \(c\) 全部提到頂端,然後將 \(c\) 移到空柱子上接著任選一個柱子將球全部分配到非滿柱子上,就遞迴為刪去這個顏色的子問題。

分析操作次數,對於每種顏色需要對每個柱子均操作一次,因此操作次數:\(\sum\limits_{i = 1} ^ n i2m + 2nm = n(n + 3)m\),已經可以通過 \(70\) 分,考慮進一步優化。

容易發現上述做法操作較多的原因是對 每種顏色 都重新做一輪,這樣事實上浪費了很多操作。

那麼能否考慮減少有效顏色的操作呢?考慮分治。

我們每次考慮將編號 \(\le mid\) 的球染成白色,剩下的球染成黑色,目標同樣是將柱子上清成同一種顏色。

令對於長度為 \(n\) 的序列操作次數為 \(f(n)\),那麼總操作次數應該為 \(f(n) \log n\),於是只需要考慮上述問題如何做即可。

類似上提的思路,我們考慮每次任選一個至少有兩種顏色的柱子 \(x\),然後再任選一個 \(y \ne x\),在沒有完成目標時總能做到。

\(x_0, x_1, y_0, y_1\) 分別為 \(x\) 上白球/黑球數量,\(y\) 上白球/黑球數量。

發現總存在 \(x_0 + y_0 \ge m\)\(x_1 + y_1 \ge m\),不妨設 \(x_0 + y_0 \le m, x_1 + y_1 \ge m\)

於此同時,我們不妨設 \(x_0 \le y_0 \le \frac{m}{2}\)

我們首先對 \(x\) 將白球上提,消耗次數 \(2m + 2x_0\)

然後將 \(x\) 上的白球全部移動到空柱子上,消耗次數 \(x_0\)

\(y\) 上的球從上到下考慮,若頂端球為白色,那麼移動到空柱子上,否則移動到 \(x\) 上直到 \(x\) 上球滿為止,至多操作 \(x_0 + y_0\) 次。

最後將 \(n + 1\) 上的球全部運回 \(y\) 上,消耗次數 \(x_0 + y_0\)

這樣 \(x\) 上的球全部變為黑色,且因為 \(x_0 + y_0 \le m\) 所以空柱子上球不會爆出來。

計算上面的總次數:\(2m + 5x_0 + 2y_0 \le 5.5m\),因此我們做到了總操作次數 \(5.5nm\log n\)

帶入滿分的資料範圍大約是 \(660000\) 次,可以輕鬆通過。

當然可以底層直接實現 \(70\) 分的 \(n(n + 3)m\) 次操作的小常數做法,可能可以達到更優的次數。

D

首先考慮一個暴力,先判掉無解的情況。

注意到題目需要求所有初始局面的存活時間,於是我們類似期望存活時間的轉化,令 \(f(x)\) 為初始位置為 \(x_1, x_2, \cdots x_m\) 的存活時間,那麼答案為:

\[\sum\limits_t ^ \infty \sum\limits_x [f(x) \ge t] \]

這等價於令 \(f(t)\) 表示 \(t\) 時刻任然存活的初始局面數量,那麼答案為:

\[\sum\limits_t ^ \infty f(t) \]

此時我們發現,\(f(t)\) 的數量是每個維度存活數量的積,那麼每個維度之間就是相互獨立的了。

注意到有效時間至多隻有 \(nw\) 天,於是可以考慮列舉天數然後暴力維護當天每個維度依然存活的數量,複雜度 \(\mathcal{O}(nmw)\)

考慮優化這個過程,顯然問題在於如何優化暴力列舉天數部分。

\(f_i(t)\) 為維度 \(i\) 在時刻 \(t\) 依然存活的初始狀態數量,此時我們有如下關鍵觀察(證明不難):

  • \(f_i(t)\) 在時刻 \(n + 1\)(也即第二輪)開始呈週期長度為 \(n\) 的定值長度減少。

同時我們可以觀察到減少的定值長度為 \(q_i = \sum\limits_{j = 1} ^ n [c_j = i] \times d_j\)

那麼我們令總共經過了 \(t\) 整輪 後就不存在局面存活了,那麼第 \(2 \sim t\) 輪的貢獻可以描述為:

\[\begin{aligned} \sum\limits_{i = 2} ^ t \sum\limits_{j = 1} ^ n \prod\limits_{k = 1} ^ m f_k(n + j) - q_k \times (i - 2) \\ \end{aligned} \]

不妨做簡單變換:\(t \leftarrow t - 2, f_i(n + j) \leftarrow f_i(j)\),那麼上式即:

\[\begin{aligned} & \ \ \ \ \ \sum\limits_i ^ t \sum\limits_{j = 1} ^ n \left(\prod\limits_{k = 1} ^ m f_k(j) - q_k \times i\right) \\ &= \sum\limits_{i = 1} ^ n \sum\limits_j ^ t \left(\prod\limits_{k = 1} ^ m f_k(i) - q_k \times j\right) \end{aligned} \]

\(g_i(j) = \prod\limits_{k = 1} ^ m f_k(i) - q_k \times j\),容易發現這是一個僅與 \(i\) 有關的 \(m\) 次多項式,於是上式等價於求 \(n\) 個給定的 \(m\) 次多項式的字首點值的和。

有經典結論 \(m\) 次多項式的非負字首點值和為一個 \(m + 1\) 次多項式,於是我們就可以插值得到 \(x = t\) 處的點值。

複雜度 \(\mathcal{O}(nm ^ 2)\),瓶頸在於計算 \(n\) 個多項式 \(0 \sim m + 1\) 處的點值。

有點輕微卡常,需要將拉格朗日插值換成連續點值的 \(\mathcal{O}(m)\) 插值。

GO!