Cod sursa(job #478204)

Utilizator jeanFMI - Petcu Ion Cristian jean Data 17 august 2010 19:47:14
Problema Pod Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.73 kb
#include<stdio.h>
#include<vector>
#include<algorithm>
#define Kmax 30
#define MMax 1010
#define Mod 9901
using namespace std;

int M[Kmax][Kmax], S[Kmax][Kmax], C[Kmax][Kmax], i, j, k, L[MMax], X[Kmax], n, m, K, gauri, idx, val;

vector<int> V;

void init ()
{
	int i,j;
	
	for( i = 1 ; i <= K ; i++ )
		for( j = 1 ; j <= K ; j++ )
			M[i][j] = 0;
	
	for( i = 1 ; i < K ; i++ )
		M[i][i+1] = 1 ;
	M[K][1] = M[K][K] = 1;
}

void copiaza (int A[Kmax][Kmax], int B[Kmax][Kmax])
{
	int i,j;
	
	for( i = 1 ; i <= K ; i++ )
		for( j = 1 ; j <= K ; j++ )
			A[i][j] = B[i][j];
		
}

void inmulteste (int A[Kmax][Kmax], int B[Kmax][Kmax])
{
	int i,j,k;
	
	for( i = 1 ; i <= K ; i++ )
		for( j = 1 ; j <= K ; j++ )
			C[i][j] = 0;
	
	for( i = 1 ; i <= K ; i++ )
		for( j = 1 ; j <= K ; j++ )
			for( k = 1 ; k <= K ; k++ )
			{
				C[i][j]+= A[i][k] * B[k][j] ;  
				if( C[i][j] > Mod ) C[i][j] %= Mod;
			}
	
	copiaza(A,C);
}

void lgput ( int b )
{
	int i,j;
	
	for( i = 1 ; i <= K ; i++ )
		for( j = 1 ; j <= K ; j++ )
			S[i][j] = 0;
	
	init();
	
	for( i = 1 ; i <= K ; i++ ) S[i][i] = 1 ;
	
	for( ; b ; b>>=1, inmulteste(M,M) )
		if(b&1) 
			inmulteste(S,M);
	
	copiaza(M,S);
}

int main()
{
	freopen("pod.in","r",stdin);
	freopen("pod.out","w",stdout);
	
	scanf("%d %d %d",&n,&m,&K);
	
	
	for( i = 1 ; i <= m ; i++ )
		scanf("%d",&L[i]);
	
	sort(L+1,L+m+1);
	
	if( L[m] == n || K > n && m ) { printf("0"); return 0; }
	if( K == n && m ) { printf("1");  return 0; }
	if( K == n &&!m ) { printf("2");  return 0; }
	
	L[ ++m ] = n + 1 ; 
	
	X[0] = 1; i = 1;
	
	for ( j = 1 ; j < K ; j++ )
	{
		X[j] += max(0,X[j-1]) ;
		
		if( L[i] == j ) 
		{
			gauri++;
			X[j] = -1;
			i++;
		}
	}
	
	X[j] = 1 + max(0,X[j-1]) ;
	
	if( L[i] == j ) 
	{
		gauri++;
		X[j] = -1;
		i++;
	}
	
	idx = K ; 
	
	for( j = 1 ; j <= K ; j++ )
		V.push_back(X[j]);
	
	X[0] = 0;
	
	while(1)
	{
		while ( gauri ) 
		{
			idx++;
			
			val = max(V[0],0) + max(V[K-1],0) ;
			
			if ( val > Mod ) val %= Mod;
			
			if( idx == L[i] ) 
			{
				val = -1 ;
				i++;
				gauri++;
			}
			
			V.push_back(val);
			
			if(V[0] == -1 ) gauri--;
			
			V.erase(V.begin());
			
			if( idx == n ) break;
		}
		
		if( idx == n ) break;
		
		lgput( L[i] - idx - 1 ) ;
			
		for( j = 1 ; j <= K ; j++ )
			X[j] = 0 ; 
		
		for( j = 1 ; j <= K ; j++ )
			for( k = 1 ; k <= K ; k++ )
			{
				X[j] += M[j][k] * V[k-1] ;
				if( X[j] > Mod ) X[j] %= Mod;
			}
		
		for( j = 1 ; j <= K ; j++ )
			V[j-1] = X[j] ;
		
		if( i == m ) break;
		
		idx = L[i]; i++;
		
		V.erase(V.begin());
		V.push_back(-1);
		
		gauri++;
	}
	
	printf("%d",V[K-1]);
	
	return 0;
}