Cod sursa(job #110335)

Utilizator DITzoneCAdrian Diaconu DITzoneC Data 26 noiembrie 2007 11:25:03
Problema NKPerm Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.8 kb
#include <stdio.h>
#include <map>
#include <vector>

using namespace std;

#define VI vector <char>
#define EPS 1e-3
#define FOR(i,s,d) for(i=(s);i<(d);++i)
#define pb push_back

map <long long,long double> H;
int n,k,T,p[256],m;

inline long long f(VI x)
{
	long long i,aux=0;
	FOR(i,1,k+2)
		aux=(aux<<5)+x[i];
	return aux;
}

long double doit(VI x)
{
	long double aux=H[f(x)];
	if(aux>EPS)
		return aux;
	if(aux<-EPS)
		return 0;
	int i,z,l=x[k+1];
	for(i=1;i<=k;++i)
	{
		z=x[i]-(i==l);
		if(z<=0) continue;
		x[i]--,x[i-1]++;
		x[k+1]=i-1;
		aux+=doit(x)*((long double)z);
		x[i]++,x[i-1]--,x[k+1]=l;
	}
	if(aux>EPS)
		H[f(x)]=aux;
	else
		H[f(x)]=-1;
	return aux;		
}

int main()
{
	int ii,i,iii,l,j;
	char s[16];
	long double nr,aux;
	freopen("nkperm.in","r",stdin);
	freopen("nkperm.out","w",stdout);
	scanf("%d %d %d",&n,&k,&T);
	m=n*k;

	VI x; 
	x.clear();
	FOR(i,0,k+2) x.pb(0); x[0]=n;
	FOR(i,0,n) x[k+1]=i, H[f(x)]=1;
	x[0]=0, x[k]=n, x[k+1]=k+1;
	doit(x);
	FOR(ii,0,T)
	{
		scanf("%s",s);
		if(s[0]=='B')
		{
			scanf("%Lf",&nr);
			x.clear();
			FOR(i,0,n) p[i]=k;
			FOR(i,0,k+2) x.pb(0); x[k]=n; x[k+1]=n;
			l=n;
			FOR(iii,0,m)
			{
				FOR(i,0,n) if(p[i]&&i!=l)
				{
					x[p[i]]--;
					x[--p[i]]++;
					x[k+1]=p[i];
					aux=doit(x);
					if(aux>nr-EPS)
					{
						l=i;
						printf("%d ",i+1);
						break;
					}
					nr-=aux;					
					x[p[i]]--;
					x[++p[i]]++;
				}
			}
			printf("\n");
		}
		else
		{
			nr=0;
			x.clear();
			FOR(i,0,n) p[i]=k;
			FOR(i,0,k+2) x.pb(0); x[k]=n; x[k+1]=n;
			l=n;
			FOR(iii,0,m)
			{
				scanf("%d",&j);
				FOR(i,0,j) if(p[i]&&i!=l)
				{
					x[p[i]]--;
					x[--p[i]]++;
					x[k+1]=p[i];
					aux=doit(x);
					if(i!=j-1)
					{
						x[p[i]]--;
						x[++p[i]]++;
						nr+=aux;
					}
					else
						l=i;
				}
			}
			printf("%.0Lf\n",nr+1);

		}
	}
	return 0;
}