Cod sursa(job #184235)

Utilizator DorinOltean Dorin Dorin Data 23 aprilie 2008 12:32:41
Problema NKPerm Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.72 kb
# include <cstdio>
# include <vector>
# include <cstring>
# include <map>
# include <set>
# include <queue>
# include <fstream>

using namespace std;

# define input "nkperm.in"
# define output "nkperm.out"

# define maxim(a,b) (a>b?a:b)
# define minim(a,b) (a<b?a:b)
# define abs(a) (a<0?-a:a)

const long long lim=(long long)1<<55;

map <int, long long> c;
# define m ((k)*(n))

char tip;
int n,k,T;

ifstream fin ( input );
ofstream fout ( output );

int getcode(int * a,int ret)
{
	 int val=1;
	 for(int i = 1; i <= k; i++)
		 ret+= a[i] * val,val*=n+1;

	 return ret;
}

long long numara(int * a, int last)
{
	 long long ret;
	 int x;
	 x = getcode(a,last);
     if(c[x])return c[x];
     if( a[k] == n ) return 1;
     ret = 0;
     for(int i = 0; i < k ; i++)
         if(a[i])
         {
                 a[i]--;
                 a[i+1]++;
                 if(i == last)
                     ret+= (long long)a[i] * numara(a,i+1);
                 else
                     ret+= (long long)(a[i] + 1) * numara(a,i+1);
                 a[i]++;
                 a[i+1]--;
                 if(ret >= lim) {
                        c[x] = lim;
                        return lim;
                 }
         }
     c[x] = ret;
     return ret;
}

void detA()
{
     long long ret = 0;
     int i;
	 int aparitii[21]={0};
	 int numar[6]={0},perm[101];
	 numar[0] = n;
     
	 perm[0] = 0;
	 for(i = 1; i<= m; i++)
		   fin >> perm[i];
	 for(i = 1; i <= m; i++)
	 {
		   for(int x = 1; x < perm[i]; x++)
		   {
               if(x != perm[i-1] && aparitii[x] < k)
               {
			       numar[aparitii[x]]--;
			       numar[aparitii[x]+1]++;

    			   ret += numara(numar,aparitii[x]+1);

	    		   numar[aparitii[x]]++;
		    	   numar[aparitii[x]+1]--;
               }
		   }
		   aparitii[perm[i]]++;
		   numar[aparitii[perm[i]]]++;
           numar[aparitii[perm[i]] - 1] --;
     }


	 fout << ret+1 << "\n";
}
void detB()
{
	long long r = 0,x;
	int ultim  = 0;
	fin >> x;

	int numar[6] = {0},aparitii[21] = {0};
	numar[0] = n;
	int i,j;

	for(i = 1; i <= m; i++)
	{
		for( j = 1; j<=n;j++)
			if(j != ultim && aparitii[j] < k)
			{
				numar[aparitii[j]] --;
				aparitii[j] ++;
				numar[aparitii[j]] ++;
				r = numara(numar,aparitii[j]);
				if(r >= x) break;
				x -= r;
				numar[aparitii[j]]--;
				aparitii[j]--;
				numar[aparitii[j]]++;
			}
		ultim = j;
		fout << j << " ";
	}

	fout << "\n";
}

int main()
{
	fin >> n >> k >> T;
    while(T--)
    {
       fin >> tip;
       switch(tip)
       {
           case 'A' : detA(); break;
           case 'B' : detB(); break;
       }
    }
    
    return 0;
}