Cod sursa(job #478658)

Utilizator mathboyDragos-Alin Rotaru mathboy Data 19 august 2010 17:18:40
Problema Pod Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.86 kb
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>

#define maxM 1010
#define maxK 30
#define mod 9901

using namespace std;

int dp[maxK][maxK], dpI[maxK][maxK], vec[maxM], mat[maxK][maxK], rmat[maxK][maxK];
int K, n, m, F[maxK], dst;
void mul (int A[maxK][maxK], int B[maxK][maxK])
{
	int i, j, k, AUX[maxK][maxK];
	for (i = 0; i <= K; i++)
		for (j = 0; j <= K; j++)
		{
			AUX[i][j] = 0;
			for (k = 0; k <= K; k++)
				AUX[i][j] = (AUX[i][j] + 1LL * A[i][k] * B[k][j]) % mod;
		}
	memcpy (A, AUX, sizeof (AUX));
}
void init ()
{
	memset (mat, 0, sizeof (mat));
	memset (rmat, 0, sizeof (rmat));
	memset (dpI, 0, sizeof (dpI));
	int i;
	for (i = 0; i < K; i++)
		mat[i + 1][i] = 1;
	mat[1][K] = 1; mat[K][K] = 1;
	for (i = 0; i <= K; i++)
		rmat[i][i] = 1;
}
void debug (int A[maxK][maxK], int px, int py)
{
	for (int i = 0; i <= px; i++) {
		for (int j = 0; j <= py; j++)
			printf ("%d ", A[i][j]);
		printf ("\n");
	}
	//printf ("\n");
}
int main ()
{
	freopen ("pod.in", "r", stdin);
	freopen ("pod.out", "w", stdout);
	
	scanf ("%d%d%d\n", &n, &m, &K);
	int i, bx = 1;
	for (i = 1; i <= m; i++)
	{
		scanf ("%d", &vec[i]);
		if (vec[i] <= K) F[vec[i]] = 1, ++bx;
	}
	sort (vec + 1, vec + m + 1);
	
	vec[m + 1] = n;
	dp[0][0] = 1;
	
	for (i = 1; i <= K; i++)
		if (F[i] == 0) dp[0][i] = dp[0][i - 1];
	if (F[K] == 0) dp[0][K] += 1;
	vec[bx - 1] = K;
	for (i = bx; i <= m + 1; i++)
	{
		init ();
		dst = vec[i] - vec[i - 1];
		//printf ("%d\n", dst);
		
		//debug (dp, 0, K);
		//printf ("\n");
		while (dst > 0)
		{
			if (dst & 1)
				mul (rmat, mat);
			mul (mat, mat);
			dst >>= 1;
		}
		for (int j = 0; j <= K; j++)
			dpI[0][j] = dp[0][j];
		mul (dpI, rmat);
		for (int j = 0; j <= K; j++)
			dp[0][j] = dpI[0][j];
		//debug (dp, 0, K);
		if (i != m + 1)
			dp[0][K] = 0;
		//printf ("%d\n", i);
		//debug (dp, 0, K);
	}
	printf ("%d\n", dp[0][K]);
	return 0;
}