Cod sursa(job #2706502)

Utilizator PatrickCplusplusPatrick Kristian Ondreovici PatrickCplusplus Data 15 februarie 2021 09:32:16
Problema NKPerm Scor 40
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.16 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("nkperm.in");
ofstream fout("nkperm.out");

int n, k, t;
long long pw[6], stareFinala;
long long maxx = (1LL << 55);
map <pair <long long, int>, long long> memo;

void Add(long long &stare, int pos, int val){
    stare += val * pw[pos];
}

int getNr(long long &stare, int &pos){
    return (stare / pw[pos]) % 100;
}

long long dinamica(long long stare, int ultim){
    if (memo[{stare, ultim}]){
        return memo[{stare, ultim}];
    }
    if (stare == stareFinala){
        return 1;
    }
    long long res = 0;
    for (int i = 0; i < k; ++i){
        if (getNr(stare, i) != 0){
            long long newStare = stare;
            Add(newStare, i, -1);
            Add(newStare, i + 1, 1);
            if (ultim == i){
                res += 1LL * getNr(newStare, i) * dinamica(newStare, i + 1);
            }
            else{
                res += 1LL * (getNr(newStare, i) + 1) * dinamica(newStare, i + 1);
            }
            if (res > maxx){
                break;
            }
        }
    }
    return memo[{stare, ultim}] = res;
}
int main(){
    fin >> n >> k >> t;
    pw[0] = 1;
    for (int i = 1; i <= k; ++i){
        pw[i] = pw[i - 1] * 100;
    }
    stareFinala = n * pw[k];
    while (t--){
        char tip;
        fin >> tip;
        if (tip == 'A'){
            long long ans = 1;
            int last = -1;
            vector <int> fr(n + 1);
            long long stare = n;
            for (int i = 1; i <= n * k; ++i){
                int nr;
                fin >> nr;
                for (int j = 1; j < nr; ++j){
                    if (j == last){
                        continue;
                    }
                    long long newStare = stare;
                    Add(newStare, fr[j], -1);
                    Add(newStare, fr[j] + 1, 1);
                    ans += dinamica(newStare, fr[j] + 1);
                }
                last = nr;
                Add(stare, fr[nr], -1);
                Add(stare, fr[nr] + 1, 1);
                fr[nr]++;
            }
            fout << ans;
        }
        else{
            long long nr;
            fin >> nr;
            long long stare = n;
            int last = -1;
            vector <int> fr(n + 1);
            for (int i = 1; i <= n * k; ++i){
                for (int j = 1; j <= n; ++j){
                    if (j == last){
                        continue;
                    }
                    long long newStare = stare;
                    Add(newStare, fr[j], -1);
                    Add(newStare, fr[j] + 1, 1);
                    long long cnt = dinamica(newStare, fr[j] + 1);
                    if (cnt < nr){
                        nr -= cnt;
                    }
                    else{
                        fout << j << " ";
                        stare = newStare;
                        fr[j] = fr[j] + 1;
                        last = j;
                        break;
                    }
                }
            }
        }
        fout << "\n";
    }
    fin.close();
    fout.close();
    return 0;
}