Cod sursa(job #374455)

Utilizator GavrilaVladGavrila Vlad GavrilaVlad Data 17 decembrie 2009 09:49:40
Problema NKPerm Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.78 kb
#include <stdio.h>
#include <map>

using namespace std;

#define baza 22

long n, m, i, j, l, k, a, u, conf, aux[30], v[30], f[30];
long long sol, qq;
char ch;
map<long, long long> d;

long long dinamica(long nr)
{
    if(d.find(nr)!=d.end())
        return d[nr];
    long i, j;
    long x=nr, cnou=0, aux[30];
    long long val=0;
    for(i=k+1; i>=0; i--, x/=baza)
        aux[i]=x%baza;
    if(aux[0]==n) return 1;
    for(i=1; i<=k; i++)
    {
        if(!aux[i]) continue;
        aux[i]--;
        aux[i-1]++;
        cnou=0;
        for(j=0; j<=k; j++)
            cnou=cnou*baza+aux[j];
        cnou=cnou*baza+i-1;
        val+=dinamica(cnou)*(aux[i]+(aux[k+1]!=i));
        if(val>((long long) (1<<30)) * (1<<20))
        {
            val=((long long) (1<<30)) * (1<<20);
            break;
        }
        aux[i]++;
        aux[i-1]--;
    }
    d[nr]=val;
    return val;
}

int main()
{
    freopen("nkperm.in", "r", stdin);
    freopen("nkperm.out", "w", stdout);
    scanf("%d%d%d\n", &n, &k, &m);
    d[n]=1;
    while(m--)
    {
        scanf("%c", &ch);
        if(ch=='A')
        {
            for(i=0; i<n; i++)
                v[i]=k;
            sol=0;
            u=n;
            for(i=1; i<=n*k; i++)
            {
                scanf("%d", &a);
                --a;
                for(j=0; j<a; j++)
                {
                    if(v[j]==0 || j==u) continue;
                    v[j]--;
                    conf=0;
                    for(l=0; l<=k; l++)
                        f[l]=0;
                    for(l=0; l<n; l++)
                        f[v[l]]++;
                    for(l=0; l<=k; l++)
                        conf=conf*baza+f[l];
                    sol+=dinamica(conf*baza+v[j]);
                    v[j]++;
                }
                v[a]--;
                u=a;
            }
            printf("%lld\n", sol+1);
        }
        if(ch=='B')
        {
            scanf("%lld", &qq);
            for(i=0; i<n; i++)
                v[i]=k;
            u=n;
            for(i=1; i<=n*k; i++)
            {
                for(j=0; j<n; j++)
                {
                    if(v[j]==0 || j==u) continue;
                    v[j]--;
                    conf=0;
                    for(l=0; l<=k; l++)
                        f[l]=0;
                    for(l=0; l<n; l++)
                        f[v[l]]++;
                    for(l=0; l<=k; l++)
                        conf=conf*baza+f[l];
                    sol=dinamica(conf*baza+v[j]);
                    v[j]++;
                    if(sol>=qq) break;
                    qq-=sol;
                }
                printf("%d ", j+1);
                u=j;
                --v[j];
            }
            printf("\n");
        }
        scanf("\n");
    }
    return 0;
}