康拓展開和逆康拓展開

2021-08-29 01:47:40 字數 1037 閱讀 6844

康托展開就是一種特殊的雜湊函式

把乙個整數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進製數與乙個排列對應起來,即進行離散化。

他們間的對應關係可由康托展開來找到。

如我想知道321是中第幾個大的數可以這樣考慮 :

第一位是3,當第一位的數小於3時,那排列數小於321 如 123、 213 ,小於3的數有1、2 。所以有22!個。再看小於第二位2的:小於2的數只有乙個就是1 ,所以有11!=1 所以小於321的排列數有22!+11!=5個

。所以321是第6個大的數。 22!+11!是321的康托展開,但需要加1才是它的排序號。

再舉個例子:1324是排列數中第幾個大的數:第一位是1小於1的數沒有,是0個 03! 第二位是3小於3的數有1和2,但1已經在第一位了,所以只有乙個數2 12! 。第三位是2小於2的數是1,但1在第一位,所以

有0個數 01! ,所以比1324小的排列有03!+12!+01!=2個,1324是第三個大數。

#include#includeusing namespace std;

/*康拓展開,該程式預設是數字的康拓展開

x=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0!

a[n]表示當前未出現的數字集合中第幾小的數字

*/int fac=; //fac[i]表示i的階乘

int cantor(string s)

return sum; //康拓展開的序號

}int main()

; //fac[i]表示i的階乘

void invcantor(int n,int len) //n為康拓展開的結果,len為序列長度

return 0;

}

康拓展開和逆康拓展開

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

康拓展開與逆康拓展開

首先解釋一下,所謂的康拓展開,就是能夠通過乙個式子,得到乙個排列在所有排列中的按字典序排好後的位次。而逆康托展開,則是給出排列的位次,能夠計算出排列是什麼。下面先給出康拓展開的公式 其中ai 為整數,並且 0 ai ai表示原數的第 i位在當前未出現的元素中是排在第幾個 康拓展開是乙個雙射,因此常用...

康拓展開與康拓展開的逆

康拓展開一般是用於計算乙個全排列數字排在所有全排列的大小位置。那麼到底怎麼計算呢?敲重點 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是當...