Cod sursa(job #467120)

Utilizator Mishu91Andrei Misarca Mishu91 Data 28 iunie 2010 11:56:09
Problema Pod Scor 0
Compilator cpp Status done
Runda Stelele Informaticii 2010, clasele X-XII, Ziua 2 Marime 1.83 kb
#include <fstream>
#include <algorithm>
#include <cstring>

using namespace std;

const int MAX_M = 1005;
const int MAX_K = 25;
const int MOD = 9901;

ifstream fin ("pod.in");
ofstream fout ("pod.out");

int N, M, K, lipsa[MAX_M], din[MAX_K];
int mat1[MAX_K][MAX_K], mat2[MAX_K][MAX_K], sol[MAX_K][MAX_K];

void citire() {
	fin >> N >> M >> K;

	for(int i = 1; i <= M; ++i) {
		fin >> lipsa[i];
	}
	lipsa[++M] = N+1;
	sort(lipsa+1, lipsa+M+1);
}

void buildMat() {
	mat1[1][1] = mat1[K][1] = 1;

	for(int i = 2; i <= K; ++i) {
		mat1[i-1][i] = mat2[i-1][i] = 1;
	}

	for(int i = 1; i <= K; ++i) {
		sol[i][i] = 1;
	}
}

void inmult(int m1[MAX_K][MAX_K], int m2[MAX_K][MAX_K]) {
	int aux[MAX_K][MAX_K];

	for(int i = 1; i <= K; ++i)
		for(int j = 1; j <= K; ++j) {
			int vax = 0;
			
			for(int k = 1; k <= K; ++k) {
				vax = (vax + m1[i][k] * m2[k][j]) % MOD;
			}

			aux[i][j] = vax;
		}

	memcpy(m1, aux, sizeof aux);
}

void pow(int sol[MAX_K][MAX_K], int put) {
	int aux[MAX_K][MAX_K];
	memcpy(aux, mat1, sizeof mat1);

	for(; put; put >>= 1) {
		if(put & 1) {
			inmult(sol, aux);
		}

		inmult(aux, aux);
	}
}

void multMat() {
	for(int i = 1; i <= M; ++i) {
		if(lipsa[i] <= K) continue;

        pow(sol, lipsa[i] - max(K, lipsa[i-1])-1);
	
		if(lipsa[i] <= N)
			inmult(sol, mat2);
	}
}

void solve() {
	int aux[MAX_K];
	aux[0] = 1;

	for(int i = 1; i <= K; ++i) {
		aux[i] = 0;
        bool ok = 0;
		for(int j = 1; j <= M; ++j)
			if(i == lipsa[j])
				ok = true;
		if(ok) continue;

		aux[i] += aux[i-1];
		if(aux[i] > MOD)
			aux[i] -= MOD;
		if(i == K) {
			aux[i] += aux[i-K];
			if(aux[i] > MOD)
				aux[i] -= MOD;
		}
	}

	for(int i = 1; i <= K; ++i) {
		din[i] = aux[K+1-i];
	}

	int Sol = 0;

	for(int i = 1; i <= K; ++i) {
		Sol += din[i] * sol[i][1];
		Sol %= MOD;
	}

	fout << Sol;
}

int main() {
	citire();
	buildMat();
	//multMat();
	solve();
}