題意
給定一個長度為 \(2 \times n\) 的數列 \(S\)。
稱一個數列是好的,當且僅當數列中的數可以由每次刪除相鄰兩個 不同 的數的操作刪空。
求劃分該數列為若干好的字串的方案數。
Sol
集中注意力。
首先顯然長度為奇數的序列是沒法做的。
若序列存在絕對眾數,則該序列一定無法刪除,否則該序列一定能被刪空
證明:若序列不存在絕對眾數,顯然每次一定能找到兩個相鄰不相同的數進行操作,所以一定能操作完。
考慮一個簡單的 \(\text{dp}\)。
設 \(pos_{l, r} \in [0, 1]\) 表示區間 \([l, r]\) 是否存在絕對眾數。
顯然該 \(\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\) 的扔到另一邊:
注意到該式子左右只和 \(i, j\) 分別有關。
考慮對於所有的 \(i\) 預處理 \(i - 2C_i + 1\),放進一個桶裡,求字尾和。
然後對於所有的 \(j\) 直接計算答案的貢獻就完事了!
複雜度:\(O(n \log ^ 2 n)\)。