Cod sursa(job #467042)

Utilizator stocarulCosmin-Mihai Tutunaru stocarul Data 28 iunie 2010 11:07:05
Problema Pod Scor 45
Compilator cpp Status done
Runda Stelele Informaticii 2010, clasele X-XII, Ziua 2 Marime 1.94 kb
#include<cstdio>
#include<algorithm>
#define infile "pod.in"
#define outfile "pod.out"
#define modulo 9901
#define mmax 1013
#define kmax 31

using namespace std;

int del[mmax]; //scanduril prin care nu poate trece
int last[kmax]; //ultimele k valori
int n; //numarul total de scanduri
int m; //numarul de scanduri prin care nu poate trece
int k; //lungimea "sariturii"
int sol; //numarul de solutii

void erase(int a[kmax][kmax])
{
	int i,j;
	for(i=1;i<=k;++i)
		for(j=1;j<=k;++j)
			a[i][j]=0;
}

void cpy(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 init_a(int a[kmax][kmax])
{
	int i;
	erase(a);
	for(i=1;i<=k;++i)
		a[1][i]=last[i];
}

void init_b(int b[kmax][kmax])
{
	int i;
	erase(b);
	for(i=1;i<k;++i)
		b[i+1][i]=1;
	b[1][k]=b[k][k]=1;
}

void prod(int a[kmax][kmax], int b[kmax][kmax])
{
	int c[kmax][kmax];
	int i,j,l;

	erase(c);
	for(i=1;i<=k;++i)
		for(j=1;j<=k;++j)
			for(l=1;l<=k;++l)
				c[i][j]=(c[i][j]+a[i][l]*b[l][j])%modulo;
	cpy(a,c);
}

void read()
{
	int i;
	scanf("%d %d %d\n",&n,&m,&k);
	for(i=1;i<=m;++i)
		scanf("%d",&del[i]);
}

void init()
{
	int i;

	//sortam scandurile
	sort(del+1, del+m+1);

	//mai adaugam o scandura "lipsa" dupa ultima scandura
	del[++m]=n+1;

	//initializam ultimele k valori "rezolvate"
	for(i=1;i<k;++i) last[i]=0;
	last[k]=1;
}

void solve()
{
	//daca nu putem avea solutie
	if(k==1 && m) return;

	int i,j,l;
	int a[kmax][kmax];
	int b[kmax][kmax];

	for(i=1,j=0;i<=m;++i)
	{
		int lg=del[i]-j-1;
		init_a(a);
		init_b(b);
		while(lg)
		{
			if(lg&1) prod(a,b);
			prod(b,b);
			lg>>=1;
		}
		j=del[i];
		for(l=1;l<k;++l)
			last[l]=a[1][l+1];
		last[k]=0;

		/*
		for(l=1;l<=k;++l)
			printf("%d ",last[l]);
		printf("\n");
		*/
	}

	sol=last[k-1];
}

void write()
{
	printf("%d\n",sol);
}

int main()
{
	freopen(infile,"r",stdin);
	freopen(outfile,"w",stdout);

	read();
	init();
	solve();
	write();

	fclose(stdin);
	fclose(stdout);
	return 0;
}