Cod sursa(job #178145)

Utilizator razvi9Jurca Razvan razvi9 Data 14 aprilie 2008 09:38:43
Problema NKPerm Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.91 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],cate[6],a[101],i,j;
inline int getcode(int last)
{
	for(int i=1;i<=k;i++)
		last+=K[i]*cate[i];
	return last;
}
long long count(int last)
{
	int code=getcode(last);
	if(sol.find(code) != sol.end()) return sol[code];
	if(cate[k]==n) return 1;
	long long number=0;
	for(int i=0;i<k;i++)
		if(cate[i])
		{
			cate[i]--;
			cate[i+1]++;
			if(last==i)
				number+=cate[i]*count(i+1);
			else
				number+=(cate[i]+1)*count(i+1);
			cate[i+1]--;
			cate[i]++;
			if(number>=lim)
			{
				sol[code]=lim;
				return lim;
			}
		}
	sol[code]=number;
	return number;
}
inline void _a()
{
	long long number=1;
	memset(cate,0,sizeof(cate));
	memset(nr,0,sizeof(nr));
	for(i=1;i<=m;i++)
		scanf("%d",&a[i]);
	cate[0]=n;
	for(i=1;i<=m;i++)
	{
		for(j=1;j<a[i];j++)
			if(j!=a[i-1] && nr[j]<k)
			{
				cate[nr[j]]--;
				nr[j]++;
				cate[nr[j]]++;
				number+=count(nr[j]);
				cate[nr[j]]--;
				nr[j]--;
				cate[nr[j]]++;
			}
		cate[nr[a[i]]]--;
		nr[a[i]]++;
		cate[nr[a[i]]]++;
	}
	printf("%lld\n",number);
}
inline void _b()
{
	long long number,aux,last=0;
	memset(cate,0,sizeof(cate));
	memset(nr,0,sizeof(nr));
	scanf("%lld",&number);
	cate[0]=n;
	for(i=1;i<=m;i++)
	{
		for(j=1;j<=n;j++)
			if(j!=last && nr[j]<k)
			{
				cate[nr[j]]--;
				nr[j]++;
				cate[nr[j]]++;
				aux=count(nr[j]);
				if(aux>=number) break;
				number-=aux;
				cate[nr[j]]--;
				nr[j]--;
				cate[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);
	t++;
	char type;
	while(--t)
	{
		scanf(" %c ",&type);
		if(type=='A')
			_a();
		else
			_b();
	}
}