Pagini recente » Cod sursa (job #2860432) | Cod sursa (job #888569) | Cod sursa (job #2779514) | Cod sursa (job #1020825) | Cod sursa (job #1726299)
#include <fstream>
#include <vector>
#include <cstring>
#include <algorithm>
#include <unordered_map>
using namespace std;
ifstream fin("nkperm.in");
ofstream fout("nkperm.out");
typedef long long ll;
const int dimn = 21;
const int dimk = 6;
const ll inf = (1LL << 55);
int n, k;
unordered_map<int, ll> memo;
int getHash(int fr[], int last) {
int pow = 1, ret = 0;
for (int i = 0; i <= k; ++i) {
ret += pow * fr[i];
pow *= dimn;
}
ret += pow * last;
return ret;
}
void reverseHash(int hash, int fr[], int& last) {
for (int i = 0; i <= k; ++i)
fr[i] = hash % dimn, hash /= dimn;
last = hash;
}
ll countNKperm(int hash) {
if (memo.count(hash))
return memo[hash];
int fr[6], last;
reverseHash(hash, fr, last);
if (fr[0] == n)
return 1;
ll ret = 0;
for (int i = 1; i <= k; ++i) {
if (!fr[i]) continue;
fr[i]--; fr[i - 1]++;
if (i != last)
ret += (fr[i] + 1) * countNKperm(getHash(fr, i - 1));
else
ret += fr[i] * countNKperm(getHash(fr, i - 1));
fr[i]++, fr[i - 1]--;
if (ret >= inf)
return memo[hash] = inf;
}
return memo[hash] = ret;
}
void solveA(void) {
static int remain[dimn], fr[dimk];
for (int i = 1; i <= n; ++i)
remain[i] = k;
ll ans = 1; int last = 0;
for (int i = 1; i <= n * k; ++i) {
int cur; fin >> cur;
for (int j = 1; j < cur; ++j) {
if (j == last || remain[j] == 0)
continue;
remain[j]--;
memset(fr, 0, sizeof fr);
for (int index = 1; index <= n; ++index)
fr[remain[index]]++;
ans += countNKperm(getHash(fr, remain[j]));
remain[j]++;
}
remain[cur]--;
last = cur;
}
fout << ans << '\n';
}
void solveB(void) {
static int remain[dimn], fr[dimk];
ll nkIndex; fin >> nkIndex;
for (int i = 1; i <= n; ++i)
remain[i] = k;
int last = 0;
for (int i = 1; i <= n * k; ++i) {
for (int j = 1; j <= n; ++j) {
if (j == last || remain[j] == 0)
continue;
--remain[j];
memset(fr, 0, sizeof fr);
for (int index = 1; index <= n; ++index)
fr[remain[index]]++;
ll nKcnt = countNKperm(getHash(fr, remain[j]));
if (nKcnt >= nkIndex) {
fout << j << ' ';
last = j;
break;
}
nkIndex -= nKcnt;
++remain[j];
}
}
fout << '\n';
}
int main() {
int t;
fin >> n >> k >> t;
while (t--) {
char op; fin >> op;
if (op == 'A')
solveA();
else
solveB();
}
return 0;
}
//Trust me, I'm the Doctor!