Cod sursa(job #163725)

Utilizator FlorinC1996Florin C FlorinC1996 Data 22 martie 2008 19:24:39
Problema NKPerm Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.13 kb
#include <stdio.h>
#include <string>
#include <map>

using namespace std;

#define ll long long

#define maxk 110
#define maxl 6
#define maxn 21
#define stop 1LL<<55

map <int, ll> c;
int n,m,N;
int a[maxk],b[maxn];
int cate[maxl];
ll sol;

inline int convert(int x)
{
	int rez=0,i;
	for (i=0;i<=m;i++) rez = rez * (n+1) + cate[i];
	rez = rez * (n+1) + x;

	return rez;
}

ll solve(int i)
{
	int j,x = convert(i);

	ll rez = 0;

	if (c.find(x)!=c.end()) return c[x];

	if (cate[m] == n) rez = 1;
	else for (j=0;j<m;j++)
			if (cate[j])
		 	{
				cate[j]--;
				cate[j+1]++;

				ll aux = solve(j+1);

				if (j!=i) rez += 1LL * (cate[j]+1) * aux;
				else rez += 1LL * cate[j] * aux;

				cate[j]++;
				cate[j+1]--;

				if (rez >= stop) 
				{
					rez = stop;
					break;
				}
			}

	c[x] = rez;
	return rez;
}

int main()
{
	freopen("nkperm.in","r",stdin);
	freopen("nkperm.out","w",stdout);

	int T,i,j;
	char op;
	ll x,aux;

	scanf("%d %d %d ",&n,&m,&T);

	N = n * m;

	while (T)
	{
		scanf("%c ",&op);
		if (op=='A')
		{
			for (i=1;i<=N;i++) scanf("%d ",&a[i]);	 

			memset(cate,0,sizeof(cate));
			memset(b,0,sizeof(b));

			sol = 1;
			cate[0] = n;

			for (i=1;i<=N;i++)
			{
				for (j=1;j<a[i];j++) 
					if (j!=a[i-1] && b[j]<m)
					{
						cate[b[j]]--;
						b[j]++;
						cate[b[j]]++;
						
						sol += solve(b[j]);

						cate[b[j]]--;
						b[j]--;
						cate[b[j]]++;
					}

				cate[b[a[i]]]--;
				b[a[i]]++;
				cate[b[a[i]]]++;
			}
			printf("%lld\n",sol);
		}
		else {
				 memset(b,0,sizeof(b));
				 memset(cate,0,sizeof(cate));

				 cate[0] = n;

				 scanf("%lld ",&x);

				 for (i=1;i<=N;i++)
				 {
				   	for (j=1;j<=n;j++)
						if (j != a[i-1] && b[j]<m)
						{
							cate[b[j]]--;
							b[j]++;
							cate[b[j]]++;

							a[i] = j;
							aux = solve(b[j]);

							if (aux>=x) break;
							else x -= aux;

							cate[b[j]]--;
							b[j]--;
							cate[b[j]]++;
						}
				 }

				 for (i=1;i<=N;i++) printf("%d ",a[i]);
				 printf("\n");
			 }
	

		T--;
	}

	return 0;
}