Cod sursa(job #982172)

Utilizator stefanzzzStefan Popa stefanzzz Data 8 august 2013 19:02:00
Problema NKPerm Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.33 kb
#include <fstream>
#include <map>
#define MAXNK 105
#define MAXK 10
#define MAXN 25
#define MAXVAL 36028797018963968
using namespace std;
ifstream f("nkperm.in");
ofstream g("nkperm.out");

int n,k,nrt,perm[MAXNK],stare,pn[MAXK],v[MAXK],cnt[MAXN],starenoua,pnou;
long long x,a;
char c;
map<int,long long> pd;
map<int,long long>::iterator it;

void initializari();
void solveA();
void solveB();
void compute(int p);

int main()
{
    int i;
    f>>n>>k>>nrt;
    initializari();
    while(nrt--){
        f>>c;
        if(c=='A'){
            for(i=1;i<=n*k;i++)
                f>>perm[i];
            solveA();}
        else{
            f>>x;
            solveB();}}
    f.close();
    g.close();
    return 0;
}

void initializari(){
    int i;
    pn[0]=1;
    for(i=1;i<=k+2;i++)
        pn[i]=pn[i-1]*(n+1);
    pd[2*n]=1;}

void solveA(){
    int i,j,aux;
    x=0;
    v[k]=n;
    stare=pn[k]*n;
    for(i=1;i<=n;i++)
        cnt[i]=k;
    for(i=1;i<=n*k;i++){
        for(j=1;j<perm[i];j++)
            if(cnt[j]>0&&j!=perm[i-1]){
                starenoua=stare-pn[cnt[j]]+pn[cnt[j]-1]+(cnt[j]-1-v[k+1])*pn[k+1];
                it=pd.find(starenoua);
                if(it==pd.end()){
                    aux=v[k+1];
                    v[k+1]=cnt[j]-1;
                    v[cnt[j]]--;
                    v[cnt[j]-1]++;
                    cnt[j]--;
                    compute(starenoua);
                    cnt[j]++;
                    v[k+1]=aux;
                    v[cnt[j]]++;
                    v[cnt[j]-1]--;}
                x+=pd[starenoua];}
        a=perm[i];
        stare+=pn[cnt[a]-1]-pn[cnt[a]]+(cnt[a]-1-v[k+1])*pn[k+1];
        v[k+1]=cnt[a]-1;
        v[cnt[a]]--;
        v[cnt[a]-1]++;
        cnt[a]--;}
    g<<x+1<<'\n';}

void solveB(){
    int i,j,aux;
    v[k]=n;
    stare=pn[k]*n;
    for(i=1;i<=n;i++)
        cnt[i]=k;
    for(i=1;i<=n*k;i++){
        for(j=1;;j++){
            if(!(cnt[j])||j==perm[i-1])
                continue;
            starenoua=stare-pn[cnt[j]]+pn[cnt[j]-1]+(cnt[j]-1-v[k+1])*pn[k+1];
            it=pd.find(starenoua);
            if(it==pd.end()){
                aux=v[k+1];
                v[k+1]=cnt[j]-1;
                v[cnt[j]]--;
                v[cnt[j]-1]++;
                compute(starenoua);
                v[k+1]=aux;
                v[cnt[j]]++;
                v[cnt[j]-1]--;}
            a=pd[starenoua];
            if(x<=a||(x==1&&i==n*k))
                break;
            x-=a;}
        stare+=pn[cnt[j]-1]-pn[cnt[j]]+(cnt[j]-1-v[k+1])*pn[k+1];
        v[cnt[j]]--;
        v[cnt[j]-1]++;
        v[k+1]=cnt[j]-1;
        cnt[j]--;
        perm[i]=j;
        g<<j<<' ';}
    g<<'\n';}

void compute(int p){
    long long S=0;
    int aux,i;
    for(i=k;i>=1&&S<MAXVAL;i--){
        if(!v[i])
            continue;
        pnou=p+pn[i-1]-pn[i]+(i-1-v[k+1])*pn[k+1];
        it=pd.find(pnou);
        if(it==pd.end()){
            aux=v[k+1];
            v[k+1]=i-1;
            v[i]--;
            v[i-1]++;
            compute(pnou);
            v[i-1]--;
            v[i]++;
            v[k+1]=aux;}
        pnou=p+pn[i-1]-pn[i]+(i-1-v[k+1])*pn[k+1];
        S+=pd[pnou]*v[i];
        if(i==v[k+1])
            S-=pd[pnou];}
    if(S>MAXVAL)
        S=MAXVAL;
    pd[p]=S;}