Cod sursa(job #322415)

Utilizator katakunaCazacu Alexandru katakuna Data 8 iunie 2009 19:34:39
Problema NKPerm Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.38 kb
using namespace std;
#include <cstdio>
#include <algorithm>
#include <map>

char tip;
int n, k, T, nk, i, l;
int viz[32], nr[32], P[128], Sol[128];
long long X, Max;
map <int, long long> H;

FILE *g = fopen("nkperm.out", "w");

long long query( int nr[], int nru ){

	int i;
	long long rez = 0;
	long long stare = 0, pw = 1;
	for(i = 1; i <= k; i++){
		stare+= nr[i] * pw;
		pw*= n + 1;
	}
	stare+= nru * pw;
	
	if( H[stare] ) 
		return H[stare];
	
	if( nr[k] == n ){ 
		H[stare] = 1; 
		return 1; 
	}
	
	for(i = 0; i < k ; i++){
		
		if( nr[i] ){
			
			nr[i]--;
			nr[i+1]++;
			
			if( i == nru )
				rez+= nr[i] * query(nr, i+1);
			
			else
				rez+= (nr[i] + 1) * query(nr, i+1);
			
			nr[i+1]--;
			nr[i]++;
			
			if( rez > Max ){
				H[ stare ] = Max; return Max;
			}
			
		}
		
	}
	
	return rez;
}

void solve_A(){
	
	long long sol = 0;
	int i, j;
	for(i = 1; i <= nk; i++){
		for(j = 1; j < P[i]; j++)
			if( j != P[i - 1] && viz[j] < k){
				nr[ viz[j] ]--;
				viz[j]++;
				nr[ viz[j] ]++;
				sol+= query( nr , viz[j]);
				
				nr[ viz[P[i]] ]--;
				viz[P[i]]--;
				nr[ viz[P[i]] ]++;
			}
		
		nr[ viz[P[i]] ]--;
		viz[P[i]]++;
		nr[ viz[P[i]] ]++;
	}
	
	fprintf(g,"%lld\n", sol + 1);
	
}


void solve_B(){
	
	int i, j, q;
	Sol[0] = 0;
	for(i = 1; i <= nk; i++){
		for(j = 1; j <= n; j++)
			if(j != Sol[i-1] && viz[j] < k ){
				nr[ viz[j] ]--;
				viz[j]++;
				nr[ viz[j] ]++;
				q = query( nr, viz[j]);
				
				nr[ viz[j] ]--;
				viz[j]--;
				nr[ viz[j] ]++;
				
				if( X - q <= 0){
					Sol[ ++Sol[0] ] = j;
					nr[ viz[j] ]--;
					viz[j]++;
					nr[ viz[j] ]++;
					break;
				}
				
				else
					X-=q;
			}
	}
	
	for(i = 1; i <= nk; i++)
		fprintf(g,"%d ", Sol[i]);
	
	fprintf(g,"\n");
}

int main(){

	FILE *f = fopen("nkperm.in", "r");
	
	fscanf(f,"%d %d %d", &n, &k, &T);
	nk = n * k;
	
	Max = 1;
	for(i = 1; i <= 55; i++)
		Max = Max << 1;
	
	for(; T; T--){
		fscanf(f,"\n%c", &tip);
		if( tip == 'A' ){
			memset(nr, 0, sizeof(nr));
			memset(viz, 0, sizeof(viz));
			nr[0] = n;
			
			for(i = 1; i <= nk; i++)
				fscanf(f,"%d", &P[i]);
			
			solve_A();
		}
		
		else{
			memset(nr, 0, sizeof(nr));
			nr[0] = n;
			memset(viz, 0, sizeof(viz));
			fscanf(f,"%lld", &X);
			solve_B();
		}
	}
	
	fclose(f);
	fclose(g);
	
	return 0;

}