Cod sursa(job #2437430)

Utilizator Ruxandra985Nanu Ruxandra Laura Ruxandra985 Data 9 iulie 2019 15:56:07
Problema NKPerm Scor 30
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.33 kb
#include <cstdio>
#include <map>
#define BASE 37
#define MOD 1000000007

using namespace std;
int n,k;
long long INF=36028797018963968;
map <int , int> mp[30];
int b7[30],v[30],w[30];
inline int modulo (int cod){
    if (cod > MOD)
        return cod - MOD;
    if (cod < 0)
        return cod + MOD;
    return cod;
}
long long back (int apar[30] , int last , int sum , int cod){
    int i;
    long long sol = 0,sp;
    //if (apar[1] == 2 && apar[2] == 1 && apar[3] == 1 && last == 1)
      //  printf ("a");
    /// stii deja ca ai un prefix valid
    if (mp[last][cod]!=0)
        return mp[last][cod];
    if (sum == n * k)
        return 1;
    for (i=1;i<=n;i++){
        if (i!=last && apar[i] + 1 <= k){
            apar[i]++;
            cod = cod + b7[i-1];
            modulo(cod);

            sp = back(apar,i,sum+1,cod);
            if ( sol > INF - sp){

                mp[last][cod] = INF;
                return INF;

            }
            else sol += back(apar,i,sum+1,cod);

            cod = cod - b7[i-1];
            modulo(cod);
            apar[i]--;
        }
    }
    mp[last][cod] = sol;
    return sol;
}
int solve_a (){
    int i,j,cod = 0;
    long long sol = 0;
    int apar[30];
    for (i=1;i<=n;i++)
        apar[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;
                cod = cod + b7[j-1];
                modulo(cod);
                apar[j]++;
                sol = sol + back (apar , j , i , cod);
                apar[j]--;
                cod = cod - b7[j-1];
                modulo(cod);
            }
        }
        w[i] = v[i];
        cod = cod + b7[v[i]-1];
        modulo(cod);
        apar[v[i]]++;
    }
    return sol;
}
void solve_b (long long x){
    int i,j,cod = 0;
    long long p;
    int apar[30];
    for (i=1;i<=n;i++)
        apar[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;
                apar[j]++;
                cod = cod + b7[j-1];
                modulo(cod);
                p = back(apar , j , i , cod);
                if (x - p <= 0){
                    w[i] = j;
                    break;
                }
                else{
                    x-=p;
                    apar[j]--;
                    cod = cod - b7[j-1];
                    modulo(cod);
                }
            }
        }
        v[i] = w[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

    b7[0] = 1;
    for (i=1;i<=n;i++)
        b7[i] = ((long long)b7[i-1] * 7)%MOD;

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