Cod sursa(job #467241)

Utilizator jeanFMI - Petcu Ion Cristian jean Data 28 iunie 2010 13:25:37
Problema Pod Scor 30
Compilator cpp Status done
Runda Stelele Informaticii 2010, clasele X-XII, Ziua 2 Marime 1.74 kb
#include<stdio.h>
#define Mod 9901
#define Nmax 1000010

int M[30][30],i,j,n,m,k,x,best[Nmax];

void copiaza(int a[30][30], int b[30][30] )
{
	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[30][30], int b[30][30] )
{
	int i,j,l,c[30][30];
	
	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(l=1;l<=k;l++)
			{
				c[i][j]+=a[i][l]*b[l][j];
				if(c[i][j] > Mod ) c[i][j]%=Mod;
			}
	
	copiaza(a,c);
}

int lgput(int b)
{
	int i,j,sum=0,A[30][30],S[30][30];
	
	copiaza(A,M);
	
	for(i=1;i<=k;i++)
		for(j=1;j<=k;j++)
		{
			S[i][j] = 0;
			if(i==j) S[i][j]=1;
		}
	
	for( ; b ; b>>=1 )
	{
		if(b&1) 
			inmulteste(S,A);
		inmulteste(A,A);
	}

	for( i = 1 ; i <= k ; i++ )
	{
		sum+=S[k][i];
		if(sum>Mod) sum%=Mod;
	}
	
	return sum;
}

int main()
{
	freopen("pod.in","r",stdin);
	freopen("pod.out","w",stdout);
	
	scanf("%d %d %d",&n,&m,&k);
		
	if( k==1 ) 
	{
		if(!m) printf("1");
		else printf("0");
		return 0;
	}
	
	if(!m)
	{
		for(i=1;i<=m;i++)
		{	
			scanf("%d",&x);
			if(x==n) {printf("0"); return 0;}
		}
		
		M[k][1] = M[k][k] = 1;
		
		for ( i = k-1 ; i ; i-- )
			M[i][i+1] = 1;
		
		if(k<=n) printf("%d",lgput(n-k+1));
		else printf("1");
		return 0;
	}
	
	if( n < Nmax )
	{
		for(i=1;i<=m;i++)
		{	
			scanf("%d",&x);
			best[x] = -1;
			if(x==n) {printf("0"); return 0;}
		}
		
		best[0]=1;
		
		for(i=1;i<=n;i++)
			if(!best[i])
			{
				if( i-k >= 0 && best[i-k] !=-1 )
					best[i]+=best[i-k];
				
				if( i-1 >= 0 && best[i-1] !=-1 )
					best[i]+=best[i-1];
				
				if(best[i]>Mod) best[i]%=Mod;
			}
		printf("%d",best[n]);
	return 0;
	}
}