Cantor expansion is a bijection of all permutations to a natural number, which is often used for space compression when building hash tables. There are n numbers (1, 2, 3, 4, ..., n), and there can be different (n!) permutations and combinations. The Cantor expansion represents the full permutation of the current permutation and combination in n different elements. ranking in .
Inverse Cantor expansion to find the first permutation of a number.
Given n and operand k, the requirements are:
P x find the xth permutation of
n Q a permutation of n find which permutation
n<=20
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #define N 25 #define LL long long using namespace std; int n, k, a [N], vis [N]; LL jc[N]; void solve1() { LL x; scanf("%lld",&x);x--; memset(vis,0,sizeof(vis)); for (int i=n-1;i>=0;i--) { int num=x/jc[i],now=0;x%=jc[i]; for (int j=1;j<=n;j++) if (!vis[j]) { if (now==num) { vis[j]=1;printf("%d",j);if (i) cout<<' ';break; } else now++; } } cout<<endl; } void solve2() { for (int i=n;i;i--) scanf("%d",&a[i]); LL ans=0; for (int i=n-1;i>=0;i--) { LL s=0; for (int j=1;j<=i;j++) if (a[j]<a[i+1]) s++; ans+=s*jc[i]; } printf("%lld\n",ans+1); } intmain () { scanf("%d%d",&n,&k); jc[0]=1; for (int i=1;i<n;i++) jc[i]=(LL)jc[i-1]*i; for (int i=1;i<=k;i++) { char ch[2]; scanf("%s",ch); if (ch[0]=='P') solve1(); else solve2(); } return 0; }