Pagini recente » Cod sursa (job #1536308) | Cod sursa (job #1154972) | Cod sursa (job #2228155) | Cod sursa (job #1080473) | Cod sursa (job #120807)
Cod sursa(job #120807)
#include <cstdio>
#include <cstring>
#include <map>
using namespace std;
#define Nmax 21
#define Kmax 8
#define ll long long
int n, k, t;
ll INF;
int p[Nmax * Kmax];
int cnt[Nmax];
int ap[Kmax];
int pow[8];
map<int, ll> M;
void citire()
{
scanf("%d %d %d\n", &n, &k, &t);
}
ll numara(int cnt[], int nr, int ultim)
{
if (M.find(nr) != M.end())
return M[nr];
if (cnt[k] == n) return 1;
int i;
ll ret = 0;
nr -= ultim * pow[k + 1];
for (i = 0; i < k; ++i)
if (cnt[i] > 0)
{
--cnt[i];
nr -= pow[i];
++cnt[i + 1];
nr += pow[i + 1];
nr += (i + 1) * pow[k + 1];
if (i == ultim)
ret += cnt[i] * numara(cnt, nr, i + 1);
else
ret += (cnt[i] + 1) * numara(cnt, nr, i + 1);
if (ret >= INF)
{
ret = M[nr] = INF;
return ret;
}
++cnt[i];
nr += pow[i];
--cnt[i + 1];
nr -= pow[i + 1];
nr -= (i + 1) * pow[k + 1];
}
nr += ultim * pow[k + 1];
M[nr] = ret;
return ret;
}
void solve()
{
int i, j, q, ct = n * k, l, tmp;
ll nr, doi55 = 1;
char tip;
INF = 1;
INF <<= 56;
doi55 <<= 55;
pow[0] = 1;
for (i = 1; i <= k + 1; ++i)
pow[i] = pow[i - 1] * (n + 1);
for (q = 1; q <= t; ++q)
{
scanf(" %c", &tip);
if (tip == 'A')
{
for (i = 1; i <= ct; ++i)
scanf(" %d", &p[i]);
memset(cnt, 0, sizeof(cnt));
nr = 0;
for (i = 1; i <= ct; ++i)
{
for (j = 1; j < p[i]; ++j)
if (cnt[j] < k && j != p[i - 1])
{
++cnt[j];
memset(ap, 0, sizeof(ap));
for (l = 1; l <= n; ++l)
++ap[cnt[l]];
for (tmp = l = 0; l <= k; ++l)
tmp += ap[l] * pow[l];
tmp += cnt[j] * pow[k + 1];
nr += numara(ap, tmp, cnt[j]);
if (nr > INF) nr = INF;
--cnt[j];
}
++cnt[p[i]];
}
if (nr <= doi55)
printf("%lld\n", nr + 1);
else
printf("%lld\n", doi55);
}
else
{
scanf(" %lld", &nr);
memset(cnt, 0, sizeof(cnt));
for (i = 1; i <= ct; ++i)
{
for (j = 1; j <= n; ++j)
{
if (cnt[j] < k && j != p[i - 1])
{
p[i] = j;
++cnt[j];
memset(ap, 0, sizeof(ap));
for (l = 1; l <= n; ++l)
++ap[cnt[l]];
tmp = 0;
for (l = 0; l <= k; ++l)
tmp += ap[l] * pow[l];
tmp += cnt[j] * pow[k + 1];
if (numara(ap, tmp, cnt[j]) < nr)
{
nr -= numara(ap, tmp, cnt[j]);
--cnt[j];
}
else
break;
}
}
}
for (i = 1; i <= ct; ++i)
printf("%d ", p[i]);
printf("\n");
}
}
}
int main()
{
freopen("nkperm.in", "r", stdin);
freopen("nkperm.out", "w", stdout);
citire();
solve();
return 0;
}