Cod sursa(job #383267)

Utilizator CezarMocanCezar Mocan CezarMocan Data 16 ianuarie 2010 11:18:23
Problema NKPerm Scor 70
Compilator cpp Status done
Runda Lista lui wefgef Marime 2.74 kb
#include <cstdio>
#include <map>
#include <vector>
#include <cstring>
#define maxN 22

using namespace std;

int n, k, t;
int i, j, nr_ant;
int cta[maxN];
vector <int> init, pref;
map <vector <int>, int > viz;
map <vector <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]);
}

long long count(vector <int> st) {
	int i;
	vector <int> z;
	long long sol = 0;

	if (viz[st]) {
//		afis(st);
//		fprintf(stderr, "  ->  %lld\n", dnk[st]);
		return dnk[st];
	}
	viz[st] = 1;
	
	if (st[k] == n) {
		dnk[st] = 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(z);
			else
				sol = sol + st[i] * count(z);
			if (sol > (1LL << 55)) {
				sol = (1LL << 55);
				break;
			}
		}

	dnk[st] = sol;

//	afis(st);
//	fprintf(stderr, "  ->  %lld\n", dnk[st]);

	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(pref);

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

				cta[nr]++;
				pref[cta[nr]]++;
				pref[cta[nr] - 1]--;
				nr_ant = nr;
//				fprintf(stderr, "%d %lld\n", i, sol);
			}

			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) {
//						fprintf(stderr, "        %d %d \n", cta[j] + 1, k + 1);
						pref[cta[j] + 1]++;
						pref[k + 1] = cta[j] + 1;
						pref[cta[j]]--;

//						afis(pref);
//						fprintf(stderr, "\n");
//						fprintf(stderr, "ana\n");
//						fprintf(stderr, "    %lld %lld %lld\n", sum, count(pref), nr);

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

						sum = sum + count(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;
}