Cod sursa(job #467345)

Utilizator toni2007Pripoae Teodor Anton toni2007 Data 28 iunie 2010 14:27:11
Problema Pod Scor 5
Compilator cpp Status done
Runda Stelele Informaticii 2010, clasele X-XII, Ziua 2 Marime 2.46 kb
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>

using namespace std;

#define maxK 	24
#define MOD 	9901
#define maxM 	1024

int V[maxK], Mat[maxK][maxK], N, M, K, G[maxM], gaura[maxM], A[maxK][maxK], X[maxK];
vector <int> H;

void mul (int A[maxK][maxK], int B[maxK][maxK], int C[maxK][maxK]) {
	int i, j, k;

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

void mul_vect (int A[maxK][maxK], int B[maxK], int C[maxK]) {
	for (int i = 1; i <= K; ++ i)
		C[i] = 0;
	int i, j;

	for (i = 1; i <= K; ++ i)
		for (j = 1; j <= K; ++ j) {
//			fprintf(stderr, "C[%d] = A[%d][%d] * B[%d]: %d += %d * %d\n", i, i, j, j, C[i], A[i][j], B[j]);
			C[i] = (C[i] + A[i][j] * B[j]) % MOD;
		}
}

void copy (int A[maxK][maxK], int C[maxK][maxK]) {
	int i, j;

	for (i = 1; i <= K; ++ i)
		for (j = 1; j <= K; ++ j)
			C[i][j] = A[i][j];
}

void print (int V[]) {
	printf("Print v: ");
	for (int i = 1; i <= K; ++ i)
		printf("%d ", V[i]);
	puts("");
}

void priint (int V[maxK][maxK]) {
	printf("*******************\n");
	int i, j;
	for (i = 1; i <= K; ++ i) {
		for (j = 1; j <= K; ++ j)
			printf("%d ", V[i][j]);
		puts("");
	}
	printf("*******************\n");
}


void log_put (int A[maxK][maxK], int N, int C[maxK][maxK]) {
	if (N == 0)	return;
	if (N == 1) {
		copy(C, A);
		return;
	}

	int tmp[maxK][maxK];

	if (N % 2 == 1) {
		log_put(A, N / 2, C);
		mul(A, A, tmp);
		mul(tmp, C, A);
	} else {
		log_put(tmp, N / 2, C);
		mul(tmp, tmp, A);
	}

	//printf("N = %d\n", N);
//	priint(A);
}

int main () {
	int i, last;

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

	scanf("%d%d%d", &N, &M, &K);

	for (i = 1; i <= M; ++ i)
		scanf("%d", &G[i]);

	sort(G + 1, G + M + 1);

	for (i = 1; i <= M && G[i] <= K; ++ i)
		gaura[i] = 1;

	for (last = K; i <= M; ++ i) {
		H.push_back(G[i] - last);
		last = G[i];
	}
	H.push_back(N - G[M] + 1);

	V[0] = 1;
	for (i = 1; i <= K; ++ i)
		if (! gaura[i])
			V[i] = V[i - 1];
	if (! gaura[K])
		V[K] ++;

	for (i = 1; i <= K; ++ i)
		Mat[i][K - i + 1] = 1;
	Mat[K][K] = 1;

	for (i = 0; i < (int) H.size(); ++ i) {
		memset(A, 0, sizeof(A));
		log_put(A, H[i] - 1, Mat);
		mul_vect(A, V, X);
	//	printf("La x : %d\n", H[i] - 1);
	//	priint(A);

		for (int j = 1; j < K; ++ j)
			V[j] = X[j + 1];
	//	print(X);
		V[K] = 0;
	//	print(V);
	//	puts("");
	}

	printf("%d\n", X[K]);
}