#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
// 适用范围: int: n --> [0, 15] long long: n--> [0, 21]
class Cantor_Expansion{
public:
// 阶乘数组
const int fac[16] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 1932053504, 1278945280, 2004310016};
vector<int> cve, tve;
int cn;
// 下标从0开始, 返回排列在全排列中的次序.
// @ arr[] 排列数组
// @ n 排类长度
int Getid(int arr[], int n) {
int i, j, cnt, res = 0;
for (i=0; i<n; ++i) {
cnt = 0;
for (j=i+1; j<n; ++j)
if (arr[j] < arr[i]) cnt++;
res += fac[n-i-1] * cnt;
}
return res;
}
// 如果要返回排列 必须初始化
// @arr[] 初始化数组, 下标[0, n-1]
// @n 长度
void init(int arr[], int n) {
int i;
cve.clear();
for (i=0; i<n; ++i)
cve.push_back(arr[i]);
sort(cve.begin(), cve.end());
cn = n;
}
// 返回排第k的排列 排列时从 0开始的. [0, n!-1]
// @arr[] 保存答案的数组 下标从0开始
// @id 要获得的排列的名次
int GetArr(int arr[], int id) {
int i, t, cnt = 0;
tve.assign(cve.begin(), cve.end());
for (i=cn-1; i>=0; --i) {
arr[cnt++] = tve[id / fac[i]];
tve.erase(tve.begin()+(id / fac[i]));
id = id % fac[i];
}
}
}ct;
int main()
{
// 逆展开 获取排序
int i, arr[5];
int tarr[] = {3, 4, 1, 5, 2};
ct.init(tarr, 5);
ct.GetArr(arr, 1);
for (i=0; i<5; ++i)
printf("%d ", arr[i]);
// 顺展开获取id
printf("\n%d", ct.Getid(tarr, 5));
return 0;
}