Cod sursa(job #116535)

Utilizator alextheroTandrau Alexandru alexthero Data 18 decembrie 2007 20:26:19
Problema NKPerm Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.31 kb
#include <stdio.h>
#include <string.h>
#include <map>

#define nmax 21
#define kmax 6
#define nkmax 101

using namespace std;
typedef long long LL;

int crt[nkmax], cate[kmax], a[nmax], p[10];
int n, k, t, nx;
map <int, LL> M;

void precalc()
{
	p[0] = 1;
	for(int i = 1; i <= 6; i++) p[i] = p[i - 1] * (n + 1);
}

LL count(int x, int ultim)
{
	if(M.find(x + p[6] * ultim) != M.end()) return M[x + p[6] * ultim];
	if(cate[k] == n) return 1;
	LL rez = 0;
	for(int i = 0; i < k; i++)
		if(cate[i])
		{
			cate[i]--;
			cate[i + 1]++;
			nx = x + p[i + 1] - p[i];
			if(i == ultim) rez += cate[i] * count(nx, i + 1);
			else rez += (cate[i] + 1) * count(nx, i + 1);
			cate[i + 1]--;
			cate[i]++;
		}

	M[x + p[6] * ultim] = rez;
	return rez;
}

LL oper1()
{
	LL rez = 1;
	memset(a, 0, sizeof(a));
	memset(cate, 0, sizeof(cate));
	int st = n, ns;
	cate[0] = n;
	for(int i = 1; i <= n * k; i++)
	{
		for(int j = 1; j < crt[i]; j++)
			if(j != crt[i - 1] && a[j] < k)
			{
				ns = st;
				ns -= p[a[j]];
				ns += p[a[j] + 1];
				cate[a[j]]--;
				cate[a[j] + 1]++;
				rez += count(ns, a[j] + 1);
				cate[a[j] + 1]--;
				cate[a[j]]++;
			}
		a[crt[i]]++;
		cate[a[crt[i]] - 1]--;
		cate[a[crt[i]]]++;
		st -= p[a[crt[i]] - 1];
		st += p[a[crt[i]]];
	}

	return rez;
}

void oper2(LL x)
{
	LL rez = 0;
	memset(crt, 0, sizeof(crt));
	memset(a, 0, sizeof(a));
	memset(cate, 0, sizeof(cate));
	cate[0] = n;
	int st = n, ns;
	for(int i = 1; i <= n * k; i++)
	{
		for(int j = 1; j <= n; j++)
			if(j != crt[i - 1] && a[j] < k)
			{
				ns = st;
				ns -= p[a[j]];
				ns += p[a[j] + 1];
				cate[a[j]]--;
				cate[a[j] + 1]++;
				if(rez + count(ns, a[j] + 1) >= x) crt[i] = j;
				else rez += count(ns, a[j] + 1);
				cate[a[j] + 1]--;
				cate[a[j]]++;
				if(crt[i]) break;
			}
		a[crt[i]]++;
		cate[a[crt[i]] - 1]--;
		cate[a[crt[i]]]++;
		st -= a[a[crt[i]] - 1];
		st += a[a[crt[i]]];
	}
	for(int i = 1; i <= n * k; i++) printf("%d ", crt[i]); printf("\n");
}

int main()
{
	char ch;
	LL aux;

	freopen("nkperm.in", "r", stdin);
	freopen("nkperm.out", "w", stdout);
	
	scanf("%d %d %d\n", &n, &k, &t);
	precalc();
	for(int i = 1; i <= t; i++)
	{
		scanf("%c ", &ch);
		if(ch == 'A')
		{
			for(int j = 1; j <= n * k; j++) scanf("%d", &crt[j]); 
			printf("%Ld\n", oper1());
		}
		else 
		{
			scanf("%Ld", &aux);
			oper2(aux);
		}
		scanf("\n");
	}

	return 0;
}