Cod sursa(job #177849)

Utilizator razvi9Jurca Razvan razvi9 Data 13 aprilie 2008 18:22:45
Problema NKPerm Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.55 kb
#include<cstdio>
#include<map>
int n,k,m,t,max,K[6];
std::map<int,long long> sol;
const long long lim=(long long)1<<55;
int nr[21],a[101],i;
inline int getcode(int last)
{
	for(int i=1;i<=n;i++)
		last+=K[nr[i]];
	return last;
}
long long count(int last)
{
	int code=getcode(last);
	if(sol.find(code) != sol.end()) return sol[code];
	code-=last;
	long long number=0;
	for(int i=1;i<=n;i++)
		if(i!=last && nr[i]<k)
		{
			nr[i]++;
			number+=count(i);
			nr[i]--;
			if(number>lim) break;
		}
	sol[code]=number;
	return number;
}
inline void _a()
{
	long long number=1;
	for(i=1;i<=m;i++)
		scanf("%d",&a[i]);
	for(i=1;i<=n;i++)
		nr[i]=k;
	for(i=m;i>=1;i--)
	{
		nr[a[i]]--;
		while(--a[i])
			if(nr[a[i]]<k && a[i]!=a[i-1])
			{
				nr[a[i]]++;
				number+=count(a[i]);
				nr[a[i]]--;
			}
	}
	printf("%lld\n",number);
}
inline void _b()
{
	long long number,aux;
	a[0]=0;
	scanf("%lld",&number);
	for(i=1;i<=n;i++) nr[i]=0;
	i=1;
	while(i<=m)
	{
		a[i]=0;
		while(++a[i])
		{
			if(a[i]==a[i-1]) continue;
			nr[a[i]]++;
			aux=count(a[i]);
			if(aux<number)
				number-=aux;
			else
				break;
			nr[a[i]]--;
		}
		i++;
	}
	for(i=1;i<=m;i++)
		printf("%d ",a[i]);
	printf("\n");
}
int main()
{
	freopen("nkperm.in","r",stdin);
	freopen("nkperm.out","w",stdout);
	scanf("%d %d %d",&n,&k,&t);m=n*k;
	K[1]=n+1;
	for(i=2;i<=k;i++)
		K[i]=K[i-1]*(n+1);
	for(i=1;i<=n;i++)sol[K[k]*n+i]=1;
	t++;
	char type;
	while(--t)
	{
		scanf(" %c ",&type);
		if(type=='A')
			_a();
		else
			_b();
	}
}