康託の複習筆記

Biadocy發表於2021-04-18

概念

摘自百度百科。

康託展開是一個全排列到一個自然數的雙射,常用於構建雜湊表時的空間壓縮。康託展開的實質是計算當前排列在所有由小到大全排列中的順序,因此是可逆的。

康託展開

逐位計算,考慮一個排列 \(1\sim i-1\) 位已經確定的貢獻。如果 \(i\) 位置填了比 \(a_i\) 小的數,\(i+1\sim n\) 無論怎麼填都是小的。所以可以得出計算公式:

\[\sum_{i=1}^n\left(\sum_{j=i+1}^n a_j<a_i\right)\times(n-i)!+1 \]

中間那個東西可以用樹狀陣列維護。

逆康託展開

觀察到 \(\left(\sum_{j=i+1}^n a_j<a_i\right)<n-i\),這也恰恰說明逆展開是唯一的。

對於每一位都可以計算出後面小於當前位的數量,因為一些數在之前已經用過了,所以要在樹狀陣列上二分。

P1088 [NOIP2004 普及組] 火星人

如何做到 \(O(n\log n)\)

\(n\) 太大了,轉排名加上 \(m\) 再轉排列不現實。

康擴充開的實質是什麼?

如果遇見過一些奇怪的進位制應該可以想到,康擴充開其實就是階乘進位制,只不過每個位置的係數比較特殊,並不直接是該位置上的數值,而是後面數值小於該位置數值的個數。

考慮維護係數,顯然一種排列可以對應多個係數。

初始直接將 \(n\) 位置的係數加上 \(m\)

接著就是要在保證排名不變的情況下調整係數至還原後排列合法。

先來看還原的過程。從前往後,和逆康託展開一樣搞,係數即逆康託展開中除出來的個數。

那就只要保證 \(i\) 位置的係數是小於等於 \(n-i\) 的即可。

誒好像證明了是階乘進位制

不斷進位就做完啦!

相關文章