Cod sursa(job #773690)

Utilizator darrenRares Buhai darren Data 2 august 2012 13:21:34
Problema NKPerm Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.92 kb
#include <cstring>
#include <fstream>
#include <algorithm>
#include <map>

using namespace std;

const int MAXN = 21;

int N, K, T;
int X[102], fr[22];
int power[22], fullbase;
map<int, long long> P;
long long number;

inline int getdigit(int num, int what)
{
	return (num / power[what - 1]) % (K + 1);
}
long long getP(int num)
{
	if (num / MAXN == 0) return 1;
	if (P.find(num) != P.end()) return P[num];
	
	int last = num % MAXN + 1, bitn = num / MAXN;
	
	long long resultnow = 0;
	for (int i = 1; i <= N; ++i)
		if (i != last && getdigit(bitn, i) > 0)
		{
			resultnow += getP((bitn - power[i - 1]) * MAXN + (i - 1));
			if (resultnow >= (1LL << 55))
			{
				resultnow = 1LL << 55;
				break;
			}
		}
	
	P[num] = resultnow;
	return resultnow;
}

int main()
{
	ifstream fin("nkperm.in");
	ofstream fout("nkperm.out");
	
	fin >> N >> K >> T;
	
	power[0] = 1;
	for (int i = 1; i <= N + 1; ++i)
		power[i] = power[i - 1] * (K + 1);
	fullbase = power[N] - 1;
	
	for (int test = 1; test <= T; ++test)
	{
		char opt;
		
		fin >> opt;
		if (opt == 'A')
		{
			for (int i = 1; i <= N * K; ++i)
				fin >> X[i];
			
			long long result = 1;
			int basenow = fullbase;
			
			for (int i = 1; i <= N * K; ++i)
			{
				for (int j = 1; j < X[i]; ++j)
					if (j != X[i - 1] && getdigit(basenow, j) > 0)
						result += getP((basenow - power[j - 1]) * MAXN + (j - 1));
				basenow -= power[X[i] - 1];
			}
			
			fout << result << '\n';
		}
		else
		{
			fin >> number;
			--number;
			
			int basenow = fullbase, last = -1;
			for (int i = 1; i <= N * K; ++i)
			{
				int j;
				for (j = 1; j <= N; ++j)
					if (j != last && getdigit(basenow, j) > 0)
					{
						if (getP((basenow - power[j - 1]) * MAXN + (j - 1)) <= number)
							number -= getP((basenow - power[j - 1]) * MAXN + (j - 1));
						else 
							break;
					}
				
				basenow -= power[j - 1];
				
				fout << j << ' ';
				last = j;
			}
			
			fout << '\n';
		}
	}
	
	fin.close();
	fout.close();
}