康拓展開與逆康拓展開

2022-05-19 03:09:59 字數 885 閱讀 7681

首先解釋一下,所謂的康拓展開,就是能夠通過乙個式子,得到乙個排列在所有排列中的按字典序排好後的位次。而逆康托展開,則是給出排列的位次,能夠計算出排列是什麼。

下面先給出康拓展開的公式

其中ai

為整數,並且 0≤ai

ai表示原數的第

i位在當前未出現的元素中是排在第幾個

。康拓展開是乙個雙射,因此常用在hash中,比如八數碼問題。

下面我們來演示下康拓展開的具體計算過程

對於乙個1-4的組成的排列,那我們應該怎麼計算它的康拓展開值rank。

第乙個數是2,後面比它小的就只有1了,rank+=(1*(3)!)

第二個數是3,後面比它小的也只有1了,rank+=(1*(2)!)

第三個數是4,後面比它小的也只有1了,rank+=(1*1!)

最後乙個數是1,沒有比它小的數了, rank+=(0*0!)

所以最終rank = 9(排列是0)。通常我們都是從1開始,所以最終rank是10。

接下來我們再演示下逆康拓展開。

首先rank--,rank = 9;

1.9/3!,得1餘3,在未選取的數里,2前面正好有乙個1個未選取的數,所以第乙個數為2。

2.3/2!,得1餘1,在未選取的數里,3前面正好有乙個1個未選取的數(2已經被選用了),所以第二個數是3。

3.1/1!得1餘0,在未選取的數里,4前面正好有乙個1個未選取的數(2,3已經被選用了),所以第二個數是4。

4.最後乙個數只能是1了。

fac[0] = 1

;

for(int i = 1;ii)

for(int i =1;i<=n;++i)

cout

<< ans << endl;

康拓展開與康拓展開的逆

康拓展開一般是用於計算乙個全排列數字排在所有全排列的大小位置。那麼到底怎麼計算呢?敲重點 x a n n 1 a n 1 n 2 a i i 1 a 2 1 a 1 0 1 從第乙個數字開始到倒數第二個數字,計算需要計算的那個數字之後比這個數小的數字有幾個,再乘以 n x n是全排列的 數字,x是當...

康拓展開和逆康拓展開

康托展開就是一種特殊的雜湊函式 把乙個整數x展開成如下形式 x a n n a n 1 n 1 a 2 2 a 1 1 其中,a為整數,並且0 a表示1,2,3,n的排列如 按從小到大排列一共6種,就是123 132 213 231 312 321 代表的數字 1 2 3 4 5 6 也就是把10進...

康拓展開和逆康拓展開

康拓展開模板題 複雜度o n 2 的會tle 看資料就知道了 雖然某題解說可以,不知道是不是後期加強了資料 然而我還是寫了o n 2 的 include typedef long long ll ll f 1000010 const ll mod 998244353 int a 1000010 b ...