Cod sursa(job #490877)

Utilizator katakunaCazacu Alexandru katakuna Data 8 octombrie 2010 17:57:17
Problema Pod Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.96 kb
#include <cstdio>                    
#include <string.h>
#include <algorithm>
using namespace std;

#define Mmax 1010
#define Kmax 22
#define MOD 9901

int n, m, k;
int v[Mmax];
int A[Kmax][Kmax];

void citire () {
	
	scanf ("%d %d %d", &n, &m, &k);
	for (int i = 1; i <= m; i++)
		scanf ("%d", &v[i]);

	sort (v + 1, v + m + 1);
}

void inm (int A[Kmax][Kmax], int B[Kmax][Kmax]) {
	
	int i, j, l;
	int C[Kmax][Kmax];         

	for (i = 1; i <= k; i++)
		memset (C[i], 0, sizeof (C[i]));

	for (i = 1; i <= k; i++)
		for (j = 1; j <= k; j++) { 
			for (l = 1; l <= k; l++)
				C[i][j]+= (A[i][l]) * (B[l][j]);
			
			C[i][j]%= MOD;
		}
	
	for (i = 1; i <= k; i++) 
		for (j = 1; j <= k; j++) 
			A[i][j] = C[i][j];
}

void A_la_n (int n) {
	
	int i;
    int B[Kmax][Kmax];

	for (i = 1; i <= k; i++) {
		memset (A[i], 0, sizeof (A[i]));
		memset (B[i], 0, sizeof (B[i]));
	}

	B[1][k] = B[k][k] = 1;
    A[1][1] = 1;
	for (i = 2; i <= k; i++)
		B[i][i - 1] = A[i][i] = 1;

    while (n) {
		if (n&1) {
			inm (A, B);	
		}

        inm (B, B);
		n>>= 1;
	}
}

void rezolva () {
	
	int j = 0, i, l, q, p;
    int B[Kmax], C[Kmax];

	for (i = 1; i <= k; i++)
		B[i] = 1;

	B[k] = 2;

	if (m && v[1] <= k)
        for (i = v[1]; i <= k; i++)
			B[i]--;

	for (i = 1;v[i] <= k && i <= m; i++) B[ v[i] ] = 0;
	p = k;
	for (; i <= m; i++) {
		A_la_n ( v[i] - p );
		
		memset (C, 0, sizeof (C));

		for (j = 1; j <= k; j++) {
			for (l = 1; l <= k; l++) 
				C[j]+= B[l] * A[l][j];
			C[j]%= MOD;
		}


		j = i;
		for (l = v[i], q = k; l >= v[i] - k + 1; l--, q--) 
			if (l == v[j]) {
				B[q] = 0;
				j--;
			}
			else 
				B[q] = C[q];	

		p = v[i];
	}

	if (v[m] == n) {
		printf ("0");
		return ;
	}

	memset (C, 0, sizeof (C));

	A_la_n (n - p);
	for (j = 1; j <= k; j++) {
		for (l = 1; l <= k; l++)
			C[j]+= B[l] * A[l][j];
		C[j]%= MOD;
	}
	
	printf ("%d", C[k]);

}

int main () {

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

	citire ();
	rezolva ();

	return 0;
}