constint N = 5; // 定義陣列長度為 5 int a[N] = {4, 1, 5, 2, 3}; // 輸入的排列 int c[N+1]; // 樹狀數組,用於計算比當前數字小的數字個數
intpermutation_to_index(){ int fac = 1; // 階乘值,用於計算康托展開 int n = 0; // 最終的索引結果 for (int i=1; i<=N; ++i) { // 計算比當前位置數字小的數字個數 int sum = 0; for (int x=a[N-i]; x; x-=x&-x) sum += c[x]; n += fac * sum; // 將結果乘上對應的階乘值 fac *= i; // 更新階乘值 // 在樹狀數組中標記已經處理過的數字 for (int x=a[N-i]; x<=N; x+=x&-x) ++c[x]; } return n; }
for (int i=1; i<=N; i++) { int digit = n / fac; n %= fac; if (N-i) fac /= (N-i);
// binary search int ans = 0; for (int k=1<<lgN; k; k>>=1) { if (ans+k >= N) continue; int sum = 0; for (int x=ans+k; x; x-=x&-x) sum += c[x]; if (ans+k - sum <= digit) ans += k; }