Cod sursa(job #467618)

Utilizator AndreyPAndrei Poenaru AndreyP Data 29 iunie 2010 17:52:56
Problema Pod Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.77 kb
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 9901
#define M1 1010
#define K 21

int n,m,k;
int ind[M1];
int a[K][K];
int v[K];

inline void citire()
{
	scanf("%d%d%d",&n,&m,&k);
	for(int i=0; i<m; ++i)
		scanf("%d",&ind[i]);
	sort(ind,ind+m);
}

inline void mul(int a[K][K],int b[K][K])
{
	int c[K][K]={0};
	int aux;

	for(int i=1; i<=k; ++i)
	{
		for(int j=1; j<=k; ++j)
		{
			for(int t=1; t<=k; ++t)
			{
				aux=a[i][t]*b[t][j];
				aux+=c[i][j];
				if(aux>=M)
					aux%=M;
				c[i][j]=aux;
			}
		}
	}
	memcpy(a,c,sizeof(int)*K*K);
}

inline void mul(int a[K][K],int v[K])
{
	int c[K]={0};
	int aux;

	for(int i=1; i<=k; ++i)
	{
		for(int t=1; t<=k; ++t)
		{
			aux=a[i][t]*v[t];
			aux+=c[i];
			if(aux>=M)
				aux%=M;
			c[i]=aux;
		}
	}
	memcpy(v,c,sizeof(int)*K);
}

inline void initA(int a[K][K])
{
	memset(a,0,sizeof(int)*K*K);
	a[k][1]=a[k][k]=1;
	for(int i=1; i<k; ++i)
		a[i][i+1]=1;
}

inline void lgput(int a[K][K],int p)
{
	int r[K][K]={0};
	for(int i=1; i<=k; ++i)
		r[i][i]=1;
	for(; p; p>>=1)
	{
		if(p&1)
			mul(r,a);
		mul(a,a);
	}
	memcpy(a,r,sizeof(int)*K*K);
}

inline void rezolva()
{
	int i=0;
	if(m!=0)
	{
		if(ind[m-1]==n)
		{
			printf("0\n");
			return;
		}
	}
	if(m!=0 && ind[0]<k)
	{
		for(int j=1; j<=ind[0]; ++j)
			v[j]=1;
		for(; i<m && ind[i]<k; ++i)
			;
	}
	else
		for(int j=1; j<=k; ++j)
			v[j]=1;
	int last=k-1;

	for(; i<m; ++i)
	{
		initA(a);
		lgput(a,ind[i]-last);
		mul(a,v);
		v[k]=0;
		last=ind[i];
	}

	initA(a);
	lgput(a,n-last);
	mul(a,v);
	printf("%d\n",v[k]);
}

int main()
{
	freopen("pod.in","r",stdin);
	freopen("pod.out","w",stdout);

	citire();
	rezolva();

	return 0;
}