Cod sursa(job #478673)

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

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

using namespace std;
// WTF ?!! :o operatia modulo a facut sa coste ~70 puncte :|
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++)
		{
			long long x = 0;
			for (k = 0; k <= K; k++)
				x = (x + 1LL * A[i][k] * B[k][j]);
			if (x >= mod) x %= mod;
			AUX[i][j] = x;
		}
	memcpy (A, AUX, sizeof (AUX));
}
void init ()
{	
	int i, j;
	for (i = 0; i <= K; i++)
	{	
		for (j = 0; j <= K; j++)
			mat[i][j] = rmat[i][j] = 0;
		rmat[i][i] = 1;
	}
	for (i = 0; i < K; i++)
		mat[i + 1][i] = 1;
	mat[1][K] = 1; mat[K][K] = 1;
}
int main ()
{
	freopen ("pod.in", "r", stdin);
	freopen ("pod.out", "w", stdout);
	
	scanf ("%d%d%d\n", &n, &m, &K);
	int i, bx = 1, cldst;
	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 ();
		cldst = dst = vec[i] - vec[i - 1];
		while (dst > 0)
		{
			if (dst & 1)
				mul (rmat, mat);
			mul (mat, mat);
			dst >>= 1;
		}
		if (cldst)
			mul (dp, rmat);
		if (i != m + 1 && cldst)
			dp[0][K] = 0;
	}
	printf ("%d\n", dp[0][K]);
	return 0;
}