Cod sursa(job #467412)

Utilizator mihai_floreaFlorea Mihai Alexandru mihai_florea Data 28 iunie 2010 20:22:43
Problema Pod Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.78 kb
#include <cstdio>
#include <algorithm>
using namespace std;

const int MOD=9901;
const int KMAX=20;
const int MMAX=1000;

typedef int matrix[KMAX][KMAX];

int N,M,K,lipsa[MMAX],T[KMAX],S[KMAX];

void mul(matrix A,matrix B)
{
	int i,j,k;
    matrix C;
	for (i=0;i<K;++i)
		for (j=0;j<K;++j)
		{
			C[i][j]=0;
			for (k=0;k<K;++k)
				C[i][j]+= A[i][k]*B[k][j];
			C[i][j]%=MOD;
		}
	//memcpy(A,C,sizeof(A));
	for (i=0;i<K;++i)
		for (j=0;j<K;++j)
			A[i][j]=C[i][j];
}

void pow(matrix A,int n)
{
	int i,j;
	matrix B,C;
	memset(B,0,sizeof(B));
	for (int i=0;i<K;++i) B[i][i]=1;
	//memcpy(C,A,sizeof(C));
	for (i=0;i<K;++i)
		for (j=0;j<K;++j)
			C[i][j]=A[i][j];
	while (n>0)
	{
		if (n&1) mul(B,C);
		mul(C,C);
		n/=2;
	}
	//memcpy(A,B,sizeof(A));
	for (i=0;i<K;++i)
		for (j=0;j<K;++j)
			A[i][j]=B[i][j];
}

matrix A,B;

int main()
{
	int i,j,k,p,q;
	freopen("pod.in","r",stdin);
	freopen("pod.out","w",stdout);
	scanf("%d %d %d",&N,&M,&K);
	for (i=0;i<M;++i) scanf("%d",&lipsa[i]);

	for (i=0;i<K-1;++i) A[i][i+1]=1;
	A[K-1][K-1]=A[K-1][0]=1;

	sort(lipsa,lipsa+M);

	bool u[KMAX];
	fill(u,u+K,false);
	for (p=M,i=0;i<M;++i) 
		if (lipsa[i]<K) u[lipsa[i]]=true;
		else {p=i;break;}

	T[0]=1;
	for (i=1;i<K;++i)
	{
		T[i]=T[i-1];
		if (u[i]) T[i]=0;
	}

	if (K-1 >= N) { printf("%d\n",T[N]); return 0; }

	q=K-1;
	for (i=p;i<M;++i)
	{
		memcpy(B,A,sizeof(A));
		pow(B,lipsa[i]-1-q);
		for (j=0;j<K;++j)
		{
			S[j]=0;
			for (k=0;k<K;++k) S[j]+=B[j][k]*T[k];
			S[j]%=MOD;
		}
		for (j=0;j<K-1;++j) T[j]=S[j+1];
		T[K-1]=0;
		q=lipsa[i];
	}

	memcpy(B,A,sizeof(A));
	pow(B,N-q);
	for (j=0;j<K;++j)
	{
		S[j]=0;
		for (k=0;k<K;++k) S[j]+=B[j][k]*T[k];
		S[j]%=MOD;
	}

	printf("%d\n",S[K-1]);

	return 0;
}