Cod sursa(job #2437429)

Utilizator NicolaalexandraNicola Alexandra Mihaela Nicolaalexandra Data 9 iulie 2019 15:50:42
Problema NKPerm Scor 100
Compilator cpp-64 Status done
Runda Lista lui wefgef Marime 4.56 kb
#include <fstream>
#include <cstring>
#include <map>
#define DIM 101
#define BASE 21
#define INF (1LL<<55)
using namespace std;

ifstream fin ("nkperm.in");
ofstream fout ("nkperm.out");
int v[DIM],f[DIM],frecv[7];
int t,n,k,i,j;
long long nr;
char c;
map <int,long long> d;
int get_stare (int f[], int x){
    /// vreau sa obtin codul din lista cu frecvente si ultimul element care trebuie pus
    /// e ca si cum as scrie intr o alta baza numarul
    int sol = 0, p = 1;
    for (int i=0;i<=k;i++){
        sol += p*f[i];
        p *= BASE;
    }
    sol += x*p; /// trebuie neaparat sa tin cont si de ultimul element
    return sol;
}
void get_frecv (int stare, int frecv[], int &last_frecv){
    /// vreau sa obtin frecventele dintr o stare data
    /// f[0] + f[1]*21 + f[2]*21^2 + f[3]*21^3 + f[4]*21^4 + f[5]*21^5 + last_frecv*21^6
    int p = 1;
    for (int i=0;i<=k;i++){
        frecv[i] = (stare/p)%BASE;
        p *= BASE;
    }
    last_frecv = (stare/p)%BASE;
}
long long get_nr (int stare){
    /// cate permutari de lungime lg care incep cu x am
    /// cunoscand frecventele tuturor elmentelor
    /// trebuie sa tin cont de ultimul element pus in permutare si de frecv lor
    /// incerc sa autoapelez fixand urmatorul element
    /// nu conteaza ce numere am pe frecvente
    if (d.find(stare) != d.end()) /// inseamna ca am mai calculat deja pt stare
        return d[stare];
    //memset (frecv,0,sizeof frecv);
    int frecv[7], last_frecv = 0;
    get_frecv (stare,frecv,last_frecv);
    if (frecv[0] == n){
        /// inseamna ca am ajuns la un sir de lungime 0
        return 1;
    }
    long long sol = 0;
    for (int i=1;i<=k;i++){
        if (!frecv[i])
            continue;

        long long coef = frecv[i];
        if (last_frecv == i) /// nu pot sa il plasez langa unul egal cu el
            coef--;

        /// incerc sa maresc frecventa unui element, deci frecventa curenta scade
        frecv[i]--, frecv[i-1]++;
        /// acum trebuie sa reconstruim codul
        int new_stare = get_stare (frecv,i-1);
        sol += coef * get_nr (new_stare);
        if (sol >= INF){ /// nu mai are sens sa continui
            sol = INF;
            break;
        }

        /// cand mai intorc trb sa revin la frecventele initiale
        frecv[i]++, frecv[i-1]--;
    }
    d[stare] = sol;
    return sol;

}
int main (){

    fin>>n>>k>>t;

    for (;t--;){
        fin>>c;
        for (i=1;i<=n;i++)
            f[i] = k;
        if (c == 'A'){
            for (i=1;i<=n*k;i++){
                fin>>v[i];
                //poz[v[i]][i] = poz[v[i]][i-1]+1; /// cati de v[i] am pana la pozitia i
            }

            long long sol = 0;
            for (i=1;i<=n*k;i++){
                for (j=1;j<v[i];j++){
                    if (!f[j]) /// nu are sens sa mai incerc daca am frecv 0
                        continue;
                    if (j != v[i-1]){
                        /// trebuie sa obtin noile frecvente
                        f[j]--;
                        memset (frecv,0,sizeof frecv);
                        for (int val=1;val<=n;val++)
                            frecv[f[val]]++;
                        sol += get_nr(get_stare(frecv,f[j]));
                        f[j]++;
                    }}
                f[v[i]]--;
            }
            fout<<sol+1<<"\n";
            /// d[lg][i][j] - nr de permutari de lg lg, care se termina cu elementul i\
            avand frecventa j se pot forma
            /// cate permutari de lg lg se pot forma, cunoscand frecventele numerelor
            /// nr de permurari in care elementul i apare de j ori

            continue;
        }
        /// fac cam acelasi lucru
        fin>>nr;
        for (i=1;i<=n*k;i++){
            for (j=1;j<=n;j++){ /// imi aleg ce element as vrea sa pun
                if (!f[j])
                    continue;
                if (j != v[i-1]){
                    f[j]--;
                    memset (frecv,0,sizeof frecv);
                    for (int val=1;val<=n;val++)
                        frecv[f[val]]++;
                    long long val = get_nr(get_stare(frecv,f[j]));
                    f[j]++;
                    if (val < nr)
                        nr -= val;
                    else {
                        /// inseamna ca trebuie sa ma opresc aici
                        v[i] = j;
                        f[j]--;
                        break;
                    }}}
            fout<<v[i]<<" ";
        }
        fout<<"\n";
    }


    return 0;
}