Cod sursa(job #383281)

Utilizator CezarMocanCezar Mocan CezarMocan Data 16 ianuarie 2010 11:36:30
Problema NKPerm Scor 50
Compilator cpp Status done
Runda Lista lui wefgef Marime 2.85 kb
#include <cstdio>
#include <map>
#include <vector>
#include <cstring>
#define maxN 22
#define baza 22

using namespace std;

int n, k, t;
int i, j, nr_ant;
int cta[maxN];
vector <int> init, pref;
map <int, long long > dnk;
char ch;
long long sol, nr, sum;

void afis(vector <int> s) {
	int i;
	for (i = 0; i < s.size(); i++)
		fprintf(stderr, "%d ", s[i]);
}

inline int vec_to_int(vector <int> t) {
	int i, nr = 0;
	for (i = 0; i < t.size(); i++)
		nr = nr * baza + t[i];
	return nr;
}

vector <int> int_to_vec(int nr) {
	vector <int> rez, ret;
	int i;
	rez.clear();
	ret.clear();

	while (nr) {
		rez.push_back(nr % baza);
		nr /= baza;
	}

	while (rez.size() < k + 2)
		rez.push_back(0);

	for (i = rez.size() - 1; i >= 0; i--)
		ret.push_back(rez[i]);

	return ret;
}

long long count(int stare) {
	int i;
	vector <int> z, st;
	long long sol = 0;
	st.clear();
	st = int_to_vec(stare);

	if (dnk.find(stare) != dnk.end()) 
		return dnk[stare];
	
	if (st[k] == n) {
		dnk[stare] = 1;
		return 1;
	}

	for (i = 0; i < k; i++) 
		if (st[i] != 0) {
			z = st;
			z[i]--; z[i + 1]++;
			z[k + 1] = i + 1;

			if (i == st[k + 1])
				sol = sol + (st[i] - 1) * count(vec_to_int(z));
			else
				sol = sol + st[i] * count(vec_to_int(z));
			if (sol > (1LL << 55)) {
				sol = (1LL << 55);
				break;
			}
		}

	dnk[stare] = sol;

	return sol;
}

int main() {
	freopen("nkperm.in", "r", stdin);
	freopen("nkperm.out", "w", stdout);
	
	scanf("%d%d%d", &n, &k, &t);


	for (; t > 0; t--) {
		scanf(" %c ", &ch);
		if (ch == 'A') {
			pref.clear();
			for (i = 1; i <= k + 2; i++)
				pref.push_back(0);

			memset(cta, 0, sizeof(cta));

			sol = nr_ant = 0;

			pref[0] = n;
			for (i = 1; i <= n * k; i++) {
				scanf("%lld", &nr);
				for (j = 1; j < nr; j++) 
					if (j != nr_ant && cta[j] < k) {
						pref[cta[j] + 1]++;
						pref[k + 1] = cta[j] + 1;
						pref[cta[j]]--;

						sol = sol + count(vec_to_int(pref));

						pref[cta[j] + 1]--;
						pref[k + 1] = 0;
						pref[cta[j]]++;
					}

				cta[nr]++;
				pref[cta[nr]]++;
				pref[cta[nr] - 1]--;
				nr_ant = nr;
			}

			printf("%lld\n", sol + 1);
		}
		else {
			scanf("%lld", &nr);
			sum = 0;
			pref.clear();
			pref.resize(k + 2);
			pref[0] = n;
			memset(cta, 0, sizeof(cta));

			nr_ant = 0;

			for (i = 1; i <= n * k; i++) {
				sum = 0;
				for (j = 1; j <= n; j++) 
					if (j != nr_ant && cta[j] < k) {
						pref[cta[j] + 1]++;
						pref[k + 1] = cta[j] + 1;
						pref[cta[j]]--;

						if (sum + count(vec_to_int(pref)) >= nr) {
							nr -= sum;
							sol = j;
							pref[cta[j] + 1]--;
							pref[k + 1] = 0;
							pref[cta[j]]++;			
							break;
						}

						sum = sum + count(vec_to_int(pref));
					
						pref[cta[j] + 1]--;
						pref[k + 1] = 0;
						pref[cta[j]]++;
					}

				cta[sol]++;
				pref[cta[sol]]++;
				pref[cta[sol] - 1]--;
				nr_ant = sol;
				printf("%lld ", sol);
			}

			printf("\n");
		}
	}

	return 0;
}