Pagini recente » Cod sursa (job #3286611) | Cod sursa (job #634704) | Cod sursa (job #707122) | Cod sursa (job #155999) | Cod sursa (job #324986)
Cod sursa(job #324986)
#include <cstdio>
#include <map>
using namespace std;
const int N = 20;
const int BASE = N+1;
const int K = 8;
const long long REZ = ((long long)1) << 55;
int n,k,t;
map<int, long long> m;
int code ( int f[], int last ) {
int pw = 1, rez = 0;
for (int i = 0; i <= k; ++i, pw *= BASE) rez += pw*f[i];
rez += pw*last;
return rez;
}
void decode ( int code, int f[], int &last ) {
int pw = 1;
for (int i = 0; i <= k; ++i, pw *= BASE) f[i] = (code/pw) % BASE;
last = (code/pw) % BASE;
}
long long count ( int conf ) {
if (m.find(conf) != m.end())
return m[conf];
int f[K], last;
decode(conf,f,last);
if (f[0] == n) return 1;
long long rez = 0;
for (int i = 1; i <= k; ++i) {
if (f[i] != 0) {
--f[i]; ++f[i-1];
rez += (f[i] + (i != last)) * count(code(f,i-1));
if (rez > REZ) {
rez = REZ;
break;
}
++f[i]; --f[i-1];
}
}
m[conf] = rez;
return rez;
}
void a() {
int ap[N];
long long rez = 1;
int last = -1, x;
for (int i = 0; i < n; ++i) ap[i] = k;
for (int i = 0; i < n*k; ++i) {
scanf("%d",&x);
--x;
for (int j = 0; j < x; ++j) {
if (ap[j] > 0 && j != last) {
--ap[j];
int f[K];
memset(f,0,sizeof(f));
for (int t = 0; t < n; ++t) ++f[ap[t]];
rez += count(code(f,ap[j]));
++ap[j];
}
}
--ap[x];
last = x;
}
printf("%lld\n",rez);
}
void b() {
int ap[N];
int last = -1;
long long x;
scanf("%lld",&x);
for (int i = 0; i < n; ++i) ap[i] = k;
for (int i = 0; i < n*k; ++i) {
int j;
long long s = 0;
for (j = 0; j < n; ++j) {
if (ap[j] > 0 && j != last) {
--ap[j];
int f[K];
memset(f,0,sizeof(f));
for (int t = 0; t < n; ++t) ++f[ap[t]];
long long y = count(code(f,ap[j]));
++ap[j];
if (s + y >= x) break;
s += y;
}
}
x -= s;
--ap[j];
printf("%d ",j+1);
last = j;
}
printf("\n");
}
int main() {
freopen("nkperm.in","rt",stdin);
freopen("nkperm.out","wt",stdout);
scanf("%d %d %d",&n,&k,&t);
for (int i = 0; i < t; ++i) {
char cmd;
scanf(" %c ",&cmd);
if (cmd == 'A')
a(); else
b();
}
}