Cantor Expansion and Inverse Cantor Expansion

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;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325223936&siteId=291194637