Pagini recente » Cod sursa (job #29352) | Cod sursa (job #3249876) | Cod sursa (job #290265) | Cod sursa (job #28354) | Cod sursa (job #110029)
Cod sursa(job #110029)
#include <stdio.h>
#include <map>
using namespace std;
#define FIN "nkperm.in"
#define FOUT "nkperm.out"
#define MAX_N 25
#define MAX_K 10
#define BASE 21
#define VAL(i) ((cfg/pow[i])%BASE)
#define INF (1ll<<55)
#define ll long long
int N, K, T, cnt[MAX_N], pow[MAX_K];
map<int, ll> mem;
int encode(int cnt[], int prev)
{
int i, cnt2[MAX_K] = {0}, ret = 0;
for (i = 1; i <= N; ++i)
cnt2[cnt[i]]++;
for (i = 0; i <= K; ++i)
ret += cnt2[i]*pow[i];
ret += cnt[prev]*pow[K+1];
return ret;
}
ll count(int cfg)
{
char i, v, vv;
int new_cfg; ll ret = 0;
if (mem.find(cfg) != mem.end())
return mem[cfg];
if (VAL(K) == N) return 1;
char last = VAL(K+1);
for (i = 0; i < K; ++i)
{
if (!(v = VAL(i))) continue;
vv = VAL(i+1);
new_cfg = cfg-pow[i]+pow[i+1]+(i+1-last)*pow[K+1];
ret += (ll)(v-(last == i))*count(new_cfg);
if (ret >= INF) { ret = INF; break; }
}
mem[cfg] = ret;
return ret;
}
int main(void)
{
int i, j, prev;
ll x, t, ret; char op;
freopen(FIN, "r", stdin);
freopen(FOUT, "w", stdout);
pow[0] = 1;
for (i = 1; i < MAX_K; ++i)
pow[i] = pow[i-1]*BASE;
for (scanf("%d %d %d", &N, &K, &T); T; --T)
{
scanf(" %c", &op);
if (op == 'A')
{
memset(cnt, 0, sizeof(cnt));
for (prev = -1, ret = 1, i = 0; i < N*K; ++i)
{
scanf("%lld", &x);
for (j = 1; j < x; ++j)
{
if (j == prev || cnt[j] == K) continue;
cnt[j]++;
ret += count(encode(cnt, j));
cnt[j]--;
}
cnt[prev = x]++;
}
printf("%lld\n", ret);
}
else
{
scanf("%lld", &x);
memset(cnt, 0, sizeof(cnt));
for (prev = -1, ret = i = 0; i < N*K; ++i)
{
for (j = 1; j <= N; ++j)
{
if (j == prev || cnt[j] == K) continue;
cnt[j]++;
t = count(encode(cnt, j));
if ((ret += t) >= x)
{
ret -= t;
printf("%d ", j);
break;
}
cnt[j]--;
}
prev = j;
}
printf("\n");
}
}
return 0;
}