Cod sursa(job #177860)

Utilizator razvi9Jurca Razvan razvi9 Data 13 aprilie 2008 18:32:43
Problema NKPerm Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.48 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,j;
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]);
	a[0]=0;
	for(i=1;i<=n;i++)nr[i]=0;
	for(i=1;i<=m;i++)
	{
		for(j=1;j<a[i];j++)
			if(j!=a[i-1])
			{
				nr[j]++;
				number+=count(j);
				nr[j]--;
			}
		nr[a[i]]++;
	}
	printf("%lld\n",number);
}
inline void _b()
{
	long long number,aux,last=0;
	scanf("%lld",&number);
	for(i=1;i<=n;i++) nr[i]=0;
	for(i=1;i<=m;i++)
	{
		for(j=1;j<=n;j++)
			if(j!=last)
			{
				nr[j]++;
				aux=count(j);
				if(aux>=number) break;
				number-=aux;
				nr[j]--;
			}
		last=j;
		printf("%d ",j);
	}
	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();
	}
}