Cod sursa(job #116712)

Utilizator sealTudose Vlad seal Data 19 decembrie 2007 13:09:15
Problema NKPerm Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.03 kb
using namespace std;
#include<cstdio>
#include<cstring>
#include<map>
#define Nm 21
#define Km 7
#define Nrm (1ll<<55)
int P[Km],n,k;
map<int,long long> M;
map<int,bool> Viz;

long long count(int a)
{
    if(Viz[a])
        return M[a];
    Viz[a]=1;
    if(a/P[k]%(n+1)==n)
    {
        M[a]=1;
        return 1;
    }
    int i;
    
    for(i=0;i<k;++i)
    {
        if(a/P[i]%(n+1)==0)
            continue;
        if(a/P[k+1]==i)
            M[a]+=(a/P[i]%(n+1)-1)*count(a%P[k+1]-P[i]+P[i+1]+(i+1)*P[k+1]);
        else
            M[a]+=a/P[i]%(n+1)*count(a%P[k+1]-P[i]+P[i+1]+(i+1)*P[k+1]);
        if(M[a]>Nrm)
        {
            M[a]=Nrm;
            break;
        }
    }
    return M[a];
}

void solveA()
{
    int F[Nm],i,j,x,xp=-1,a=n;
    long long ans=1;

    memset(F,0,sizeof(F));
    for(i=0;i<n*k;++i)
    {
        scanf("%d",&x);
        for(j=1;j<x;++j)
            if(j!=xp && F[j]<k)
                ans+=count(a-P[F[j]]+P[F[j]+1]+(F[j]+1)*P[k+1]);
        a-=P[F[x]];
        ++F[x];
        a+=P[F[x]];
        xp=x;
    }
    printf("%lld\n",ans);
}

void solveB()
{
    int F[Nm],i,j,xp=-1,a=n;
    long long x,v;

    scanf("%lld",&x);
    memset(F,0,sizeof(F));
    for(i=1;i<=n*k;++i)
    {
        for(j=1;;++j)
            if(j!=xp && F[j]<k)
            {
                v=count(a-P[F[j]]+P[F[j]+1]+(F[j]+1)*P[k+1]);
                if(x<=v)
                    break;
                x-=v;
            }
        if(i<n*k)
            printf("%d ",j);
        else
            printf("%d\n",j);
        a-=P[F[j]];
        ++F[j];
        a+=P[F[j]];
        xp=j;
    }
}

int main()
{
    char c;
    int i,t;

    freopen("nkperm.in","r",stdin);
    freopen("nkperm.out","w",stdout);
    scanf("%d%d%d",&n,&k,&t);

    P[0]=1;
    for(i=1;i<=k+1;++i)
        P[i]=P[i-1]*(n+1);

    while(t--)
    {
        scanf(" %c",&c);
        if(c=='A')
            solveA();
        else
            solveB();
    }
    return 0;
}