Cod sursa(job #478123)

Utilizator jeanFMI - Petcu Ion Cristian jean Data 17 august 2010 14:58:15
Problema Pod Scor 15
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.31 kb
#include<stdio.h>
#define Kmax 30
#define MMax 1010
#define Mod 9901

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

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

void init ()
{
	int i;
	
	reset(M);
	
	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;
	
	reset(C);
	
	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 )
{
	reset(S); 
	init();
	
	for( int 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]);
	
	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 ; 
	
	i = 1 ; idx = 1 ; V[1] = V[K] = 1;
	
	while(1)
	{
		ok = 1; 
		
		while ( ok && i <= m ) 
		{
			ok = 0; 
			
			for( j = 1 ; j <= K && idx <= n ; j++, idx++ )
			{
				if( j==1 ) X[j]= V[1]   + V[K] ;
				else       X[j]= X[j-1] + V[j] ;
				
				if( idx == 1 ) X[1] = 1;
				
				if ( X[j] > Mod ) X[j]%=Mod;
				
				if ( idx == L[i] ) 
				{
					X[j] = 0 ;
					i++;
					ok = 1 ; 
				}
			}
			
			for( j = 1 ; j <= K ; j++ )
				V[j] = X[j] ;
			if ( idx > n ) K = j-1 ;
		}
		
		if( i > m ) break;
		
		lgput( L[i] - idx  ); 
		i++; idx+=K;
		
		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] ;
				if( X[j] > Mod ) X[j] %= Mod;
			}
		
		for( j = 1 ; j <= K ; j++ )
			V[j] = X[j] ;
		
		if( i == m ) break;
	}
	
	printf("%d",V[K]);
	
	return 0;
}