Cod sursa(job #118901)

Utilizator gcosminGheorghe Cosmin gcosmin Data 28 decembrie 2007 12:09:00
Problema NKPerm Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.39 kb
#include <stdio.h>
#include <vector>
#include <map>
using namespace std;

#define LL long long
#define INF ((LL) 1 << 55)
#define MP make_pair

int N, K;

int a[110];

map <pair<vector<int>, int>, LL> H;

LL calc(vector <int> a, int last)
{
	if (H[MP(a, last)]) return H[MP(a, last)];

	if (a[K] == N) return H[MP(a, last)] = 1;

	LL rez = 0;

	for (int i = 0; i < K; i++) {
		if (!a[i]) continue;

		a[i]--;
		a[i + 1]++;

		if (i == last) rez += a[i] * calc(a, i + 1);
		else rez += (a[i] + 1) * calc(a, i + 1);

		if (rez > INF) {
			rez = INF;
			break;
		}

		a[i]++;
		a[i + 1]--;
	}

	return H[MP(a, last)] = rez;
}

int b[110];

vector <int> get_pref(int a[], int q, int &last)
{
	int i, j, nr, w = 0, kkt;

	vector <int> rez(K + 1, 0);

	memcpy(b, a, sizeof(b));

	for (i = 1; i <= q; i++) {
		if (!b[i]) continue;

		kkt = b[i];
		nr = 0;
		for (j = i; j <= q; j++) 
			if (b[j] == kkt) {
				nr++, b[j] = 0;
				if (j == q) last = nr;
			}

		rez[nr]++;
		w++;
	}

	rez[0] = N - w;

	return rez;
}

LL get_nr(int a[], int q)
{
	int i, j, w, last, n0;
	LL rez = 0;
	vector <int> jeg;

	vector <int> nr(N + 1, 0);

	for (i = 1; i <= q; i++) {
		w = a[i];
		for (j = 1; j < a[i]; j++) {
			if (j == a[i - 1] || nr[j] == K) continue;

//			printf("-- %d %d\n", i, j);

			a[i] = j;
			jeg = get_pref(a, i, last);
			n0 = jeg[0];

/*			for (int ii = 1; ii <= i; ii++) printf("%d ", a[ii]);
			printf("\n");
			for (int ii = 0; ii <= K; ii++) printf("%d ", jeg[ii]);
			printf("\n");
			printf("%d\n\n", last);
*/
			rez += calc(jeg, last);

//			printf("%d %d - %lld\n", i, j, rez);

			a[i] = w;
		}

		nr[j]++;
	}

	return rez + 1;
}

void get_vec(LL nr)
{
	int i, j, last;
	LL rez = 0, q;
	vector <int> jeg;
	vector <int> nnr(N+1, 0);

	for (i = 1; i <= N * K; i++) {
		for (j = 1; j <= N; j++) {
			if (j == a[i - 1] || nnr[j] == K) continue;
			a[i] = j;

			jeg = get_pref(a, i, last);
			q = calc(jeg, last);
			if (rez + q < nr) rez += q;
			else break;
		}

		nnr[a[i]]++;
	}
}

int main()
{
	int T, I, i;
	char op;
	LL q;

	freopen("nkperm.in", "r", stdin);
	freopen("nkperm.out", "w", stdout);

	scanf("%d %d %d", &N, &K, &T);

	for (I = 1; I <= T; I++) {
		scanf(" %c", &op);

		if (op == 'A') {
			for (i = 1; i <= N * K; i++) scanf("%d", &a[i]);

			printf("%lld\n", get_nr(a, N * K));
		} else {
			scanf("%lld", &q);
			get_vec(q);
			for (i = 1; i <= N * K; i++) printf("%d ", a[i]);
			printf("\n");
		}
	}

return 0;
}