Pagini recente » Cod sursa (job #695993) | Cod sursa (job #108413) | Cod sursa (job #1165333) | Cod sursa (job #2199509) | Cod sursa (job #1099899)
#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();
// imi precalculez puterile de tip 2^p la matricea de tranzitie
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]);
// initializez pentru treptele 0,1,...,K - 1
nr[0] = 1; // fictiv, treapta "-1"
for(i = 1, j = 1; i <= K; ++i)
{
if(j <= m && poz[j] == i - 1)
{
// poate niste trepte stricate erau in primele K - 1
nr[i] = 0;
j++;
}
else
nr[i] = nr[i - 1];
}
if(n - K + 1 <= 0)
sol = nr[n + 1];
else
{
// fiindca inmultesc matrici (1,K) cu (K,K)
// am complexitate K^2 la inmultire, in loc de K^3
// daca as fi exponentiat clasic si abia la final inmulteam cu (1,K)
poz[j - 1] = K - 1;
while(j <= m)
{
// merg pana la urmatoarea treapta stricata
dest = poz[j] - poz[j - 1];
for(i = 0; i <= 30; ++i)
if(dest & (1 << i))
Inmulteste2(nr, mat[i]);
nr[K] = 0; // o marchez ca stricata si merg mai departe
j++;
}
// merg acum la treapta n
// se presupune ca treptele stricate erau <= n
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;
}