Cod sursa(job #2437747)

Utilizator Ruxandra985Nanu Ruxandra Laura Ruxandra985 Data 10 iulie 2019 11:20:16
Problema NKPerm Scor 40
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.18 kb
#include <cstdio>
#include <map>
#define BASE 21


using namespace std;
int n,k;
int apar[30],nr[6];
long long INF=36028797018963968;
map <int , long long> mp;
int b[7],v[110],w[110];

long long back (int fqlast){
    int i,cod = 0;
    long long sol = 0;
    /// stii deja ca ai un prefix valid

    for (i=0;i<=k;i++)
        cod = cod + b[i] * nr[i];

    cod = cod + b[k+1] * fqlast;

    if (nr[k] == n)
        return (long long)1;

    if (mp.find(cod) != mp.end())
        return mp[ cod ];

    for (i=0;i<k;i++){
        if (nr[i]){
            nr[i]--;
            nr[i+1]++;
            if (i == fqlast){
                sol += (long long)nr[i] * back(i+1);
            }
            else {
                sol += (long long)(nr[i]+1) * back(i+1);
            }

            if ( sol >= INF){

                mp[ cod ] = INF;
                return INF;

            }

            nr[i]++;
            nr[i+1]--;
        }
    }
    mp[ cod ] = sol;
    return sol;
}
long long solve_a (){
    int i,j;
    long long sol = 0;
    for (i=1;i<=n;i++)
        apar[i] = 0;

    nr[0] = n;
    for (i=1;i<=k;i++)
        nr[i] = 0;

    for (i=1;i<=n*k;i++){
        for (j=1;j<v[i];j++){
            if (j!=w[i-1] && apar[j] + 1 <=k){
                w[i] = j;
                nr[apar[j]] --;
                nr [apar[j]+1]++;
                sol = sol + back (apar[j]+1);
                nr[apar[j]] ++;
                nr [apar[j]+1]--;
            }
        }
        w[i] = v[i];
        apar[v[i]]++;
        nr[apar[v[i]]-1] --;
        nr[apar[v[i]]]++;
    }
    return sol;
}
inline void solve_b (long long x){
    int i,j;
    long long p;

    for (i=1;i<=n;i++)
        apar[i] = 0;

    nr[0] = n;
    for (i=1;i<=k;i++)
        nr[i] = 0;

    for (i=1;i<=n*k;i++){
        for (j=1;j<=n;j++){
            if (j!=w[i-1] && apar[j] + 1 <=k){
                w[i] = j;
                nr[apar[j]] --;
                nr [apar[j]+1]++;
                p = back(apar[j]+1);
                if (x - p <= 0){
                    apar[j]++;
                    w[i] = j;
                    break;
                }
                else{
                    x-=p;
                    nr[apar[j]] ++;
                    nr [apar[j]+1]--;
                }
            }
        }
        v[i] = w[i];
        //printf ("%d ",v[i]);
    }
}
int main()
{
    FILE *fin = fopen ("nkperm.in","r");
    FILE *fout = fopen ("nkperm.out","w");
    int i,t;
    long long x;
    char c;
    fscanf (fin,"%d%d",&n,&k);
    /// precalculari

    b[0] = 1;
    for (i=1;i<=k+1;i++)
        b[i] = b[i-1] * BASE;

    fscanf (fin,"%d\n",&t);
    for (;t;t--){
        c=fgetc (fin);
        if (c=='A'){
            for (i=1;i<=n*k;i++){
                fscanf (fin,"%d",&v[i]);
            }
            fgetc (fin);
            fprintf (fout,"%lld\n",solve_a() + 1);
        }
        else {
            fscanf (fin,"%lld\n",&x);
            solve_b(x);
            for (i=1;i<=n*k;i++)
                fprintf (fout,"%d ",v[i]);
            fprintf (fout,"\n");
        }
    }
    return 0;
}