Pagini recente » Cod sursa (job #2211123) | Cod sursa (job #225750) | Cod sursa (job #318216) | Cod sursa (job #380154) | Cod sursa (job #119860)
Cod sursa(job #119860)
#include <cstdio>
#include <cstring>
#include <map>
using namespace std;
long n,k,t;
long in[128];
long cate[16];
long ap[32];
struct lma{ // sursa a fost scrisa de 1 ian :) La multi ani, 2008!
long A[16], B;
};
struct comp {
bool operator()(lma fir, lma sec) {
if ( fir.B<sec.B )
return true;
return (memcmp(fir.A, sec.A, sizeof(long)*(k+1))<0);
}
};
map <lma, long long, comp> M;
/* returneaza cate permutari au un inceput dat
* Mircea a observat ceva inteligent, si anume
* ca intr-un prefix, conteaza mai putin ce
* numere sunt pe o anumita poz, mai important
* e cate numere se repeta de x ori = cate[x]
*/
long long numara(long ultim) {
if ( cate[k]==n )
return 1;
lma tmp;
memcpy(tmp.A, cate, sizeof(long)*(k+1));
tmp.B = ultim;
map<lma, long long>::iterator it = M.find(tmp);
if ( it!=M.end() ) { // exista memoizat
return it->second;
}
long long ret=0;
for (long i=0; i<k; ++i)
if ( cate[i] ) {
cate[i] --; cate[i+1] ++; // teoretic mai bagi una care aparea de i ori pana acu
if ( i==ultim )
ret += cate[i]*numara(i+1);
else
ret += (cate[i]+1)*numara(i+1);
if ( ret>1ll<<55 )
return 1ll<<55;
cate[i+1] --; cate[i]++;
}
M.insert(make_pair(tmp, ret));
return ret;
}
long long a() {
memset(cate,0,sizeof(cate));
memset(ap,0,sizeof(ap));
long long ret = 1; // TODO de ce?
cate[0] = n;
for (long i=0; i<n*k; ++i) {
for (long j=1; j<in[i]; ++j)
if ( j!=in[i-1] && ap[j] < k ) {
cate[ap[j]] --;
cate[++ap[j]]++;
ret+= numara(ap[j]);
cate[ap[j]] --;
cate[--ap[j]] ++;
}
cate[ap[in[i]]]--;
cate[++ap[in[i]]]++;
}
return ret;
}
void b(long long nr) {
memset(ap,0,sizeof(ap));
memset(cate,0,sizeof(cate));
cate[0] = n;
for (long i=0; i<n*k; ++i) {
for (long j=1; j<n; ++j)
if ( j!=in[i-1] && ap[j]<k ) {
cate[ap[j]]--; cate[++ap[j]]++;
long tmp;
if ( (tmp=numara(ap[j]))>=nr ) {
in[i] = j;
break;
} else {
nr -= tmp;
}
cate[ap[j]]--; cate[--ap[j]]++;
}
ap[in[i]]++;
}
}
int main() {
freopen("nkperm.in", "r", stdin);
freopen("nkperm.out", "w", stdout);
scanf("%ld %ld %ld\n", &n, &k, &t);
while ( t-- ) {
char c;
scanf("%c", &c);
if ( c=='A' ) {
for (long i=0; i<n*k; ++i)
scanf("%ld", in+i);
scanf("\n");
printf("%lld\n", a());
} else {
long long nr;
scanf("%lld\n", &nr);
b(nr);
for (long i=0; i<n*k; ++i)
printf("%ld ", in[i]);
printf("\n");
}
}
fclose(stdin);fclose(stdout);
return 0;
}