QOJ #8820. Exchanging Kubic 2

275307894a發表於2024-06-25

首先我們來考慮給定一個序列,如何計算最小的權值。

不妨將其差分來看,每次操作相當於向左向右找到第一個位置滿足差分值 \(>0\),然後將這兩個位置分別 \(-1\)

記三元組 \((l_i,x_i,r_i)\) 表示在 \(x\) 操作一次,左邊在第 \(l_i\) 個差分值位置處減了 \(1\),右邊在第 \(r_i\) 個差分值位置處減了 \(1\)

如果對於兩對三元組 \((l_1,x_1,r_1),(l_2,x_2,r_2)\),滿足 \(x_1<l_2<r_1<x_2\),這是不可能的,因為假設第一個三元組先操作,那麼 \(l_2\) 處肯定已經沒有值了所以才會跳過。而如果第二個三元組先操作,則 \(r_1\) 處也沒有值了。同理不能有 \(l_1<l_2<x_1<x_2\),因此,任意兩個三元組對應的區間 \([l_i,r_i]\) 只能是相離或者包含。

如果一個三元組的區間包含了另一個三元組的區間,那麼被小的三元組就要早於大的三元組操作,這顯然是一個 DAG。因此只要我們確定了一些三元組滿足不交或者包含,那麼就是合法的。

然後就可以看出,三元組的兩邊是獨立的,也即 \(l_i\)\(r_i\) 沒有關係,只需要分別滿足 \(\leq x\)\(\geq x\) 即可。

這變成一個匹配問題,容易得到一個貪心:從左到右對於每個差分值,先找 \(\leq x\) 能填的填進去,然後找 \(\geq x\) 能填的填進去即可。

然後可以 DP 了,設 \(f_{i,j,k}\) 表示到了第 \(i\) 個數,選了 \(j\),差分值總和是 \(k\)。若 \(k<i\),則說明前面有值沒有用到,補齊成 \(i\)。若 \(k>n+i-1\),說明空位太多了,則 \(k-(n+i-1)\) 就會被計入答案。這個 DP 容易字首和最佳化到 \(O(n|S|(n+|S|))\)

submission

相關文章