Cod sursa(job #339974)

Utilizator AndreiDDiaconeasa Andrei AndreiD Data 12 august 2009 14:10:09
Problema NKPerm Scor 0
Compilator cpp Status done
Runda Lista lui wefgef Marime 2.56 kb
#include <cstdio>
#include <cstring>
#include <map>

using namespace std;


#define file_in "nkperm.in"
#define file_out "nkperm.out"

#define Nmax 110


int p[Nmax];
int cate[Nmax];
int cat[Nmax];
int ap[Nmax];
int n,k,m,nk;
map<int, long long> h;
char c;
long long maxim,x;

long long numara(int cate[], int ultim)
{
	int ind=0;
	int put=1,i;
	long long rez;
	
	for (i=0;i<=k;++i)
	{
		ind+=put*cate[i];
		put*=(n+1);
	}
	
	ind+=put*ultim;
	
	if (h[ind]!=0)//a mai fost
		return h[ind];
	
	if (cate[k]==n)
	{
        h[ind]=1;
		return 1;
	}
	
	rez=0;
	for (i=0;i<k;++i)
	{
		if (cate[i]!=0)
		{
			cate[i]--;
	  	    cate[i+1]++;
		    if (i==ultim)
			    rez+=((long long)cate[i])*numara(cate,i+1);
		    else
		    if (i!=ultim)
		 	    rez+=((long long)cate[i]+1)*numara(cate,i+1);
			cate[i+1]--;
			cate[i]++;
		}
		
		if (rez>maxim)
		{
			h[ind]=maxim;
			return maxim;
		}
		
	}
	
	h[ind]=rez;
	
	
	return rez;
}
		
long long querya()
{
	memset(ap,0,sizeof(ap));
	memset(cat,0,sizeof(cat));
	
	cat[0]=n;
	
	long long rez=1;
	int i,j;
	
	for (i=1;i<=n*k;++i)
	{
		for (j=1;j<p[i];++j)
			 if (j!=p[i-1] && ap[j]<k)
			 {
				cat[ap[j]]--;
				ap[j]++;
				cat[ap[j]]++;
				
				rez+=numara(cat,ap[j]);
				
				cat[ap[j]]--;
				ap[j]--;
				cat[ap[j]]++;
			 }
			 
		cat[ap[p[i]]]--;
		ap[p[i]]++;
		cat[ap[p[i]]]++;
	}				
	
	return rez;
}


void queryb(long long x)
{
	
	long long rez=0;
	int i,j,ok;
	
	memset(ap,0,sizeof(ap));
	memset(cat,0,sizeof(cat));
	
	cat[0]=n;
	
	for (i=1;i<=n*k;++i)
	{
		ok=0;
		for (j=1;j<=n && !ok;++j)
			 if (j!=p[i-1] && ap[j]<k)
			 {
				cat[ap[j]]--;
				ap[j]++;
				cat[ap[j]]++;
				
                if (rez+numara(cat,ap[j])>=x)
				{
					p[i]=j;
					ok=1;
    			}
				else
				{
					rez+=numara(cat,ap[j]);
				}
				
				cat[ap[j]]--;
				ap[j]--;
				cat[ap[j]]++;
				
			 }
	    
		cat[ap[p[i]]]--;
		ap[p[i]]++;
		cat[ap[p[i]]]++;
		
	}
	
	for (i=1;i<=n*k;++i)
		 printf("%d ", p[i]);
	printf("\n");
}

int main()
{
	int i,j;
	freopen(file_in,"r",stdin);
	freopen(file_out,"w",stdout);
	
	scanf("%d %d %d\n", &n,&k,&m);
	
	
	maxim=1;
	//2^55
	for (i=1;i<=55;++i)
		 maxim=maxim*2;
	
	while(m--)
	{
		scanf(" %c", &c);
		if (c=='A')
		{
			for (i=1;i<=n*k;++i)
				 scanf("%d", &p[i]);
			
			printf("%d\n", querya()+1);
		}
		else
		if (c=='B')
		{
			scanf("%lld", &x);
			queryb(x);
		}
		scanf("\n");
	}
	
	fclose(stdin);
	fclose(stdout);
	
	return 0;
}