Sol

Chax發表於2024-03-11

Sol0310

隨機逆序對

題意

給定 \(1\sim n\) 的排列 \(a_{1...n}\) 。在上面進行依次如下操作:

  1. 首先在\([1,n]\)​中選取一個子序列(可以為空);

  2. 然後將這個子序列內的數重新排列。

兩個操作不同,當且僅當選取的子序列不同或者重新排列的方式不同。對於所有不同的操作,求他們產生的排列的逆序對個數和,答案對\(10^9+7\)​取模。

題解

首先,看到這個題目我們發現整體方案數並不好列舉,所以說考慮拆分貢獻。

我們先思考樸素的 \(O(n^3)\) 的做法,我們列舉 \(3\) 個元素分別為目前逆序對會產生貢獻的兩個數字,以及目前選了多少個數字。我們設 \(pos_i\)\(i\) 這個值在序列中的位置那麼我們就可以得到以下式子。

1.\(pos_i\)\(>pos_j\)

方案數分別為我們隻影響到 \(2\) 個數字,的貢獻要算 \(4\) 倍是因為這兩個點不一定全部都要在交換序列中,因為他們本身順序都是一樣的。然後就是我們影響到 \(3\) 個位置的,有幾種情況。分別是 \(i\)\(j\) 不動,\(i\) 不動 \(j\) 動,\(i\)\(j\) 的位置 \(j\) 動, \(j\)\(i\) 的位置 \(i\) 動,情況數也是好統計的,和之前的差不多可以自行證明。最後就是 \(4\) 個位置的情況,也很簡單,直接列舉除了 \(i,j\) 兩個點的位置即可。 唯一需要注意的是有些時候有些位置並不需要在選擇的需要排列的序列中導致的貢獻增加,記得細心推式子。

\[4\sum\limits_{i=1}^{n}\sum\limits_{j=i+1}^{n}\sum\limits_{k=2}^{n}C^{n-2}_{k-2}(k-2)! +2\sum\limits_{i=1}^{n}\sum\limits_{j=i+1}^{n}\sum\limits_{k=3}^{n}C^{n-3}_{k-3}(k-3)!(n-pos_j-1) +2\sum\limits_{i=1}^{n}\sum\limits_{j=i+1}^{n}\sum\limits_{k=2}^{n}C^{n-3}_{k-3}(k-3)!(pos_i-2) +\sum\limits_{i=1}^{n}\sum\limits_{j=i+1}^{n}\sum\limits_{k=2}^{n}C^{n-3}_{k-3}(k-3)!(pos_j-1) +\sum\limits_{i=1}^{n}\sum\limits_{j=i+1}^{n}\sum\limits_{k=2}^{n}C^{n-3}_{k-3}(k-3)!(n-pos_i) +\sum\limits_{i=1}^{n}\sum\limits_{j=i+1}^{n}\sum\limits_{k=2}^{n}C^{n-4}_{k-4}(k-4)!\frac{(n-3)\times(n-2)}{2} \]

2.\(pos_i<pos_j\)

情況和上述差別不大可以自行推導。

\[\sum\limits_{i=1}^{n}\sum\limits_{j=i+1}^{n}\sum\limits_{k=2}^{n}C^{n-2}_{k-2}(k-2)! +2\sum\limits_{i=1}^{n}\sum\limits_{j=i+1}^{n}\sum\limits_{k=3}^{n}C^{n-3}_{k-3}(k-3)!(n-pos_j) +2\sum\limits_{i=1}^{n}\sum\limits_{j=i+1}^{n}\sum\limits_{k=2}^{n}C^{n-3}_{k-3}(k-3)!(pos_i-1) +\sum\limits_{i=1}^{n}\sum\limits_{j=i+1}^{n}\sum\limits_{k=2}^{n}C^{n-3}_{k-3}(k-3)!(pos_j-2) +\sum\limits_{i=1}^{n}\sum\limits_{j=i+1}^{n}\sum\limits_{k=2}^{n}C^{n-3}_{k-3}(k-3)!(n-pos_i-1) +\sum\limits_{i=1}^{n}\sum\limits_{j=i+1}^{n}\sum\limits_{k=2}^{n}C^{n-4}_{k-4}(k-4)!\frac{(n-3)\times(n-2)}{2} \]

我們可以發現其實後面的 \(k\) 其實可以不用列舉,每一次的結果都是一樣的,係數也是相同所以可以直接預處理就可以把時間複雜度降到 \(O(n^2)\)

最後我們發現其實我們只用列舉 \(i\) ,但其實 \(j\) 的加起來的和和數量是可以維護的,所以說只需要寫一個樹狀陣列維護即可。時間複雜度降到了 \(O(n\log n)\)。可以透過此題。