1. 程式人生 > 其它 >2021CCPC網路預選賽(重賽) 【待補完】

2021CCPC網路預選賽(重賽) 【待補完】

比賽連結
過了6題。遺憾的是1008我推的式子漏了一種情況,最後一小時都沒看出來。太可惜了。

1008

分析:

分成兩部分來算。第一部分是在每個n排列內部的m排列,可以直接算:

$ (n-m+1) * m! * (n-m)! $

第二部分是在兩個n排列之間的m排列。
首先,設兩個相鄰的n排列是p1和p2,那麼p2就是:找到p1的最長下降字尾s,將s的前一個數字x與s中大於x的最小數字y交換,再把y後面的部分從小到大排序。
想清楚這點就好說了。當時我這裡想錯了,以為x是與s中的最小數字交換囧。
然後可以確定的是,如果p1和p2之間有m排列,那麼p1的形態一定是:
一段 $ [1,m] $ 的數(記作A) + 一段 $ [m+1,n] $ 的數(記作B) + 一段 $ [1,m] $ 的數(記作C)。
證明這一點需要用到p1到p2的變化規律:
如果p1是上述形態,易知p2的形態是 $ A + ... $ ,那麼p1的C和p2的A組成一個m排列。
如果p1不是上述形態,要想滿足條件,p1總要存在一個字尾C滿足:C中的數都 $ \in [1,m] $ 。那麼它需要p2的形態是 $ A + ... $,其中A由 $ [1,m] $ 去掉C中的數後剩下的陣列成。根據變化規律可知p1一定有字首A。這是由於p1的最長下降字尾的開頭不會是首部(稱第一個大於m的數字之前為首部)的後一個數字(因為首部後面、C前面還有 $ \in [1,m] $ 的數),則p1到p2首部不會改變。所以p1的首部是A,與假設矛盾。
然後我們考慮變化發生在C內的情況:只要C不是遞減的,那麼p1到p2的變化發生在C內,那麼可以得到m排列。這部分的答案是:

$ \sum_{i=1}^{m-1} C_{m}^{i} * (i!-1) * (m-i)! * (n-m)! $

然後當時我以為C遞減的情況就不能得到m排列了,導致WA了半天最終沒過……
實際上C是遞減的情況也可以得到答案。只要不是從A往後都遞減,那麼p2的首部就還是A。所以這部分的答案是:

$ \sum_{i=1}^{m-1} C_{m}^{i} * (m-i)! * ( (n-m)! - 1 ) $

全部加起來,總答案是:

$ m! * (n-m)! * n - m! * \sum_{i=1}^{m-1} \frac{1}{i!} $

預處理就可以 $ O(1) $ 得到每次的答案了。