[ARC159F] Good Division

cxqghzj發表於2024-05-05

題意

給定一個長度為 \(2 \times n\) 的數列 \(S\)

稱一個數列是好的,當且僅當數列中的數可以由每次刪除相鄰兩個 不同 的數的操作刪空。

求劃分該數列為若干好的字串的方案數。

Sol

集中注意力。

首先顯然長度為奇數的序列是沒法做的。

若序列存在絕對眾數,則該序列一定無法刪除,否則該序列一定能被刪空

證明:若序列不存在絕對眾數,顯然每次一定能找到兩個相鄰不相同的數進行操作,所以一定能操作完。

考慮一個簡單的 \(\text{dp}\)

\(pos_{l, r} \in [0, 1]\) 表示區間 \([l, r]\) 是否存在絕對眾數。

\[f_i = \sum_{j = 0} ^ {i - 2} [i - j \mod 2][pos_{j + 1, i}]f_j \\ \]

顯然該 \(\text{dp}\) 的複雜度為 \(O(n ^ 2)\)

考慮使用 \(\text{CDQ}\) 分治最佳化。

注意到對於大多數情況,左邊所有的狀態都能直接轉移到右邊。

考慮先將左邊求和,先轉移,然後再減去絕對眾數產生的貢獻。

若一個序列有絕對眾數,則它任意分成兩段,至少有一段存在絕對眾數

我們可以考慮分別處理出 \(\text{mid}\) 左邊與右邊的絕對眾數。

顯然能夠成為絕對眾數的數的個數不會超過 \(\log n\)

考慮 \(s_p\) 能成為絕對眾數的約束,設 \(i, j\) 為當前選擇區間的左右端點,顯然 \(i \le mid\),且 \(j > mid\)。設 \(C_i, C_j\) 分別表示 \(mid\) 左邊與右邊,和 \(s_p\) 相同的數的個數。

由絕對眾數的定義得:

\[(i - j + 1) < (C_i + C_j) \times 2 \]

考慮化簡:

\[i - j + 1 < 2C_i + 2C_j \]

將含 \(i\) 的扔到一邊,含 \(j\) 的扔到另一邊:

\[i - 2C_i + 1 < j + 2C_j \]

注意到該式子左右只和 \(i, j\) 分別有關。

考慮對於所有的 \(i\) 預處理 \(i - 2C_i + 1\),放進一個桶裡,求字尾和。

然後對於所有的 \(j\) 直接計算答案的貢獻就完事了!

複雜度:\(O(n \log ^ 2 n)\)

相關文章