Cod sursa(job #322138)

Utilizator vanila_CPPIonescu Victor Cristian vanila_CPP Data 8 iunie 2009 04:47:45
Problema NKPerm Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.59 kb
#include <iostream>
#include <map>
#define FIN "nkperm.in"
#define FOUT "nkperm.out"
#define MAXK 10
#define BAZA 21
#define MAXN 25
using namespace std;
int howmuch[MAXK];
map<int,long long> dyn;
int cate[MAXN];
int N,M,K;
int Perm[MAXN*MAXK];
long long P2;


long long count(int howm[],int last){

	int indice=0;
	int i,pw;
	for (i=0,pw=1;i<=K;++i){

		indice+=pw*howm[i];
		pw*=7;
	}
	indice+=pw*last;
	if (dyn[indice]){ return dyn[indice];}
	if (howm[K]==N){ dyn[indice]=1; return 1;}

	long long sum=0;

	for (int i=0;i<K;++i){

		if (howm[i]){

			--howm[i];
			++howm[i+1];

			if (i==last) sum+=((long long)howm[i])*count(howm,i+1);
			if (i!=last) sum+=((long long)howm[i]+1)*count(howm,i+1);
						++howm[i];
			--howm[i+1];
			if (sum>P2){ dyn[indice]=P2;return P2;}

			
		}
	}
	dyn[indice]=sum;

	return sum;
}

long long query1(void){

	memset(cate,0,sizeof(cate));
	memset(howmuch,0,sizeof(howmuch));
	howmuch[0]=N;
	long long sum=0;

	for (int i=1;i<=N*K;++i){

		for (int valoare=1;valoare<Perm[i];++valoare)
			if (valoare!=Perm[i-1] && cate[valoare]<K){

				--howmuch[cate[valoare]];
				++cate[valoare];
				++howmuch[cate[valoare]];
				
				sum+=count(howmuch,cate[valoare]);

				--howmuch[cate[valoare]];
				--cate[valoare];
				++howmuch[cate[valoare]];
			}
		--howmuch[cate[Perm[i]]];
		++cate[Perm[i]];
		++howmuch[cate[Perm[i]]];

	}

	return sum;
}

void query2(long long NR){

	long long sum=0;
	memset(cate,0,sizeof(cate));
	memset(howmuch,0,sizeof(howmuch));
	howmuch[0]=N;

	for (int i=1;i<=N*K;++i){

		for (int j=1;j<=N;++j)
			if (j!=Perm[i-1] && cate[j]<K){

				--howmuch[cate[j]];
				++cate[j];
				++howmuch[cate[j]];

				if ((sum+count(howmuch,cate[j]))>=NR){
					Perm[i]=j;
					--howmuch[cate[j]];
				--cate[j];
				++howmuch[cate[j]];
					j=N+1;
				} else {
					sum+=count(howmuch,cate[j]);
				

				--howmuch[cate[j]];
				--cate[j];
				++howmuch[cate[j]];}
			}
		--howmuch[cate[Perm[i]]];
		++cate[Perm[i]];
		++howmuch[cate[Perm[i]]];
	}

	for (int i=1;i<N*K;++i) printf("%d ",Perm[i]);
	printf("%d\n",Perm[N*K]);
}


int main(void){

	freopen(FIN,"rt",stdin);
	freopen(FOUT,"wt",stdout);

	scanf("%d %d %d\n",&N,&K,&M);
	char c;

	P2=1;
	for (int i=1;i<=55;++i) P2*=2;

	for (int i=1;i<=M;++i){

		c=getchar();
		if (c=='A'){ 
			for (int i=1;i<=N*K;++i) scanf("%d",&Perm[i]);
			printf("%lld\n",query1()+1);
		} else {
			long long NR;
			scanf("%lld",&NR);
			query2(NR);
		}
		scanf("\n");
	}

	fclose(stdin);
	fclose(stdout);
	return 0;
}