Pagini recente » Diferente pentru autumn-warmup-2007/solutii/runda-2 intre reviziile 42 si 56 | Cod sursa (job #632893) | Cod sursa (job #1403432) | Istoria paginii preoni-2007/clasament | Cod sursa (job #116427)
Cod sursa(job #116427)
#include <stdio.h>
#include <string.h>
#include <vector>
#include <map>
#define nmax 21
#define kmax 6
#define pb push_back
using namespace std;
typedef long long LL;
typedef pair<vector<int>, int> vi;
map <vi, LL> M;
int n, k;
int crt[nmax * kmax], a[kmax];
vi init;
LL inf;
LL count(vi x)
{
if(M.find(x) != M.end()) return M[x];
if(x.first[k] == n) return 1;
LL rez = 0;
vi ns;
for(int i = 0; i < k; i++)
if(x.first[i])
{
ns = x;
ns.first[i]--;
ns.first[i + 1]++;
ns.second = i + 1;
if(i == x.second) rez += (x.first[i] - 1) * count(ns);
else rez += x.first[i] * count(ns);
if(rez > inf)
{
rez = inf;
M[x] = rez;
return rez;
}
}
M[x] = rez;
return rez;
}
LL oper1()
{
LL rez = 1;
memset(a, 0, sizeof(a));
vi st = init, ns;
for(int i = 1; i <= n * k; i++)
{
for(int j = 1; j < crt[i]; j++)
if(j != crt[i - 1] && a[j] < k)
{
ns = st;
ns.first[a[j]]--;
ns.first[a[j] + 1]++;
ns.second = a[j] + 1;
rez += count(ns);
}
a[crt[i]]++;
st.first[a[crt[i]] - 1]--;
st.first[a[crt[i]]]++;
}
return rez;
}
void oper2(LL x)
{
LL rez = 0;
memset(a, 0, sizeof(a));
vi st = init, ns;
for(int i = 1; i <= n * k; i++)
{
for(int j = 1; j <= n; j++)
if(j != crt[i - 1] && a[j] < k)
{
ns = st;
ns.first[a[j]]--;
ns.first[a[j] + 1]++;
ns.second = a[j] + 1;
if(rez + count(ns) >= x)
{
crt[i] = j;
break;
}
else rez += count(ns);
}
a[crt[i]]++;
st.first[a[crt[i]] - 1]--;
st.first[a[crt[i]]]++;
}
for(int i = 1; i <= n * k; i++) printf("%d ", crt[i]); printf("\n");
}
int main()
{
char ch;
int t;
LL a1;
inf = (LL)1 << 56;
freopen("nkperm.in", "r", stdin);
freopen("nkperm.out", "w", stdout);
scanf("%d %d %d\n", &n, &k, &t);
init.first.pb(n);
for(int i = 1; i <= k; i++) init.first.pb(0);
init.second = 0;
for(int i = 1; i <= t; i++)
{
scanf("%c ", &ch);
if(ch == 'A')
{
for(int j = 1; j <= n * k; j++) scanf("%d", &crt[j]);
scanf("\n");
printf("%Ld\n", oper1());
}
else
{
scanf("%Ld\n", &a1);
oper2(a1);
}
}
return 0;
}