Cod sursa(job #1099884)

Utilizator scipianusFMI Ciprian Olariu scipianus Data 6 februarie 2014 13:29:58
Problema Pod Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.54 kb
#include <fstream>
#include <algorithm>
#define MOD 9901
using namespace std;
int n, m, K, poz[1010], nr[22], sol;
int mat[31][22][22];

inline void Inmulteste(int A[22][22], int B[22][22], int C[22][22])
{
	int i, j, k;
	for(i = 1; i <= K; ++i)
	{
		for(j = 1; j <= K; ++j)
		{
			for(k = 1; k <= K; ++k)
				C[i][j] += A[i][k] * B[k][j];
			C[i][j] %= MOD;
		}
	}
}

inline void Inmulteste2(int A[22], int B[22][22])
{
	int i, j, C[22];
	for(i = 1; i <= K; ++i)
	{
		C[i] = 0;
		for(j = 1; j <= K; ++j)
			C[i] += A[j] * B[j][i];
		C[i] %= MOD;
	}
	for(i = 1; i <= K; ++i)
		A[i] = C[i];
}

int main()
{
	int i, j, dest;
	ifstream fin("pod.in");
	fin >> n >> m >> K;
	for(i = 1; i <= m; ++i)
		fin >> poz[i];
	sort(poz + 1, poz + m + 1);
	fin.close();
	
	for(i = 2, j = 1; i <= K; ++i, ++j)
		mat[0][i][j] = 1;
	mat[0][1][K] = mat[0][K][K] = 1;
	for(i = 1; i <= 30; ++i)
		Inmulteste(mat[i - 1], mat[i - 1], mat[i]);
	nr[0] = 1;
	for(i = 1, j = 1; i <= K; ++i)
	{
		if(j <= m && poz[j] == i - 1)
		{
			nr[i] = 0;
			j++;
		}
		else
			nr[i] = nr[i - 1];
	}
	
	if(n - K + 1 <= 0)
		sol = nr[n + 1];
	else
	{
		poz[j - 1] = K - 1;
		while(j <= m)
		{
			dest = poz[j] - poz[j - 1];
			for(i = 0; i <= 30; ++i)
				if(dest & (1 << i))
					Inmulteste2(nr, mat[i]);
			nr[K] = 0;
			j++;
		}
		dest = n - poz[j - 1];
		for(i = 0; i <= 30; ++i)
			if(dest & (1 << i))
				Inmulteste2(nr, mat[i]);
		sol = nr[K];
	}
	
	ofstream fout("pod.out");
	fout << sol << "\n";
	fout.close();
	return 0;
}