Cod sursa(job #1204932)

Utilizator misinozzz zzz misino Data 4 iulie 2014 14:03:54
Problema NKPerm Scor 100
Compilator cpp Status done
Runda Lista lui wefgef Marime 2.54 kb
#include<fstream>
#include<map>
#include<cstring>

#define N 8
#define INF 1LL << 55

using namespace std;

ifstream f("nkperm.in");
ofstream g("nkperm.out");

int i,k,conf,n,j,uc,p[110],put[22],frecv[22];

char op;

long long t,x,sol;

map<int,long long>m;

inline int ct(int x,int i){
    return (x / put[i]) % (n + 1);
}

inline long long rez(int x){
    if(x / N == put[k] * n)
        return 1;

    if(m.find(x) != m.end())
        return m[x];

    int uc = x % N;
    int conf = x / N;

    long long sol = 0;

    for(int i = 0 ; i < k ; ++ i)
    {
        int cate = ct(conf, i);
        if(cate - (i == uc) > 0)
            sol += 1LL * (cate - (i == uc)) * rez((conf + put[i + 1] - put[i]) * N + i + 1);

        if(sol >= INF)
        {
            sol = INF;
            break;
        }
    }

    m[x] = sol;

    return sol;
}

int main()
{
    f >> n >> k >> t;

    put[0] = 1;
    for(i = 1 ; i <= k + 1 ; ++ i)
        put[i] = put[i - 1] * (n + 1);

    for(; t ; -- t)
    {
        f >> op;

        if(op == 'A')
        {
            for(i = 1 ; i <= n * k ; ++ i)
                f >> p[i];

            memset(frecv,0,sizeof(frecv));

            sol = 1;

            for(i = 1 ; i <= n * k ; ++ i)
            {
                conf = 0;

                for(j = 1 ; j <= n ; ++ j)
                    conf += put[frecv[j]];

                for(j = 1 ; j < p[i] ; ++ j)
                    if(j != p[i - 1] && frecv[j] < k)
                    sol += rez((conf - put[frecv[j]] + put[frecv[j] + 1]) * N + frecv[j] + 1);

                ++ frecv[p[i]];
            }

            g << sol << '\n';
        }
        else
        {
            f >> x;
            -- x;

            memset(frecv,0,sizeof(frecv));

            uc = -1;
            conf = n;
            for(i = 1 ; i <= n * k ; ++ i)
            {
                for(j = 1 ; j <= n ; ++ j)
                    if(j != uc && frecv[j] < k)
                    {
                        if(rez((conf + put[frecv[j] + 1] - put[frecv[j]]) * N + frecv[j] + 1) <= x)
                            x -= rez((conf + put[frecv[j] + 1] - put[frecv[j]]) * N + frecv[j] + 1);
                        else
                            break;
                    }
                g << j << ' ';

                conf -= put[frecv[j]];
                ++ frecv[j];
                conf += put[frecv[j]];

                uc = j;
            }
            g << '\n';
        }
    }

    return 0;
}