Cod sursa(job #2487217)

Utilizator FunnyStockyMihnea Andreescu FunnyStocky Data 4 noiembrie 2019 11:15:28
Problema NKPerm Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.53 kb
#include <iostream>
#include <cstdio>
#include <vector>
#include <map>

using namespace std;

typedef long long ll;
const ll INF = (ll) 1e18;

ll add(ll a, ll b)
{
    a += b;
    if (a <= INF)
    {
        return a;
    }
    else
    {
        return INF;
    }
}

ll mul(ll a, ll b)
{
    if (a == 0 || b == 0)
    {
        return 0;
    }
    if (a == INF || b == INF)
    {
        return INF;
    }
    ll c = a * b;
    if (c % a == 0 && c / a == b && c <= INF)
    {
        return c;
    }
    else
    {
        return INF;
    }
}

int n, k, t;

map<pair<vector<int>, int>, ll> sol;

void print(vector<int> c, int last)
{
    cout << " -> ";
    for (auto &x : c)
    {
        cout << x << " ";
    }
    cout << ", " << last << " ";
}

void calc(vector<int> c, int last) /// c[i] <= n, last <= k
{
    if (sol.count({c, last}))
    {
        return;
    }

    if (c[0] == n)
    {
        sol[{c, last}] = 1;
        return;
    }

    ll ans = 0;
    for (int i = 1; i <= k; i++)
    {
        if (c[i])
        {
            c[i]--;
            c[i - 1]++;

            calc(c, i - 1);
            ans += sol[{c, i - 1}] * (c[i] + 1 - (last == i));

            c[i]++;
            c[i - 1]--;
        }
    }
    sol[{c, last}] = ans;
}

int f[21];

vector<int> make()
{
    vector<int> c(k + 1);
    for (int i = 0; i <= k; i++)
    {
        c[i] = 0;
    }
    for (int i = 1; i <= n; i++)
    {
        c[f[i]]++;
    }
    return c;
}

void print(ll id)
{
    id--;
    for (int i = 1; i <= n; i++)
    {
        f[i] = k;
    }

    int last = -1;
    for (int i = 1; i <= n * k; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            if (f[j] && j != last)
            {
                f[j]--;
                vector<int> c = make();
                calc(c, f[j]);
                ll cur = sol[{c, f[j]}];

                if (cur <= id)
                {
                    id -= cur;
                    f[j]++;
                }
                else
                {
                    cout << j << " ";
                    last = j;
                    break;
                }
            }
        }
    }
    cout << "\n";
}

ll solve(vector<int> a)
{
    for (int i = 1; i <= n; i++)
    {
        f[i] = k;
    }
    f[1]--;
    vector<int> c = make();
    f[1]++;

    calc(c, n - 1);
    ll ans = (a[0] - 1) * sol[{c, n - 1}];


    for (int i = 0; i < n * k; i++)
    {
        /// pana la i sunt egale
        if (i == n * k - 1)
        {
            ans++;
            continue;
        }
        f[a[i]]--;
        for (int j = 1; j < a[i + 1]; j++)
        {
            if (j == a[i])
            {
                continue;
            }
            f[j]--;
            vector<int> c = make();
            calc(c, f[j]);
            ans += sol[{c, f[j]}];
            f[j]++;
        }
    }

    return ans;
}

int main()
{
    freopen ("nkperm.in", "r", stdin);
    freopen ("nkperm.out", "w", stdout);

    cin >> n >> k >> t;

    while (t--)
    {
        string s;
        cin >> s;

        if (s == "A")
        {
            vector<int> a(n * k);
            for (int i = 0; i < n * k; i++)
            {
                cin >> a[i];
            }
            cout << solve(a) << "\n";
        }
        else
        {
            ll id;
            cin >> id;
            print(id);
        }
    }





    return 0;
}