Pagini recente » Cod sursa (job #1094032) | Cod sursa (job #665564) | Cod sursa (job #3244311) | Cod sursa (job #1916771) | Cod sursa (job #467085)
Cod sursa(job #467085)
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define MAX_M 1010
#define MAX_K 30
#define prim 9901
int n, m, k, poz;
int c[MAX_K], d[MAX_K];
int obst[MAX_M];
int mat[MAX_K][MAX_K], init[MAX_K][MAX_K], aux[MAX_K][MAX_K];
void inm_mat(int put) {
if (put == 1)
return;
inm_mat(put / 2);
memset(aux, 0, sizeof(aux));
for (int t = 1; t <= k; t++)
for (int i = 1; i <= k; i++)
for (int j = 1; j <= k; j++)
aux[i][j] = (aux[i][j] + mat[i][t] * mat[t][j]) % prim;
for (int i = 1; i <= k; i++)
for (int j = 1; j <= k; j++)
mat[i][j] = aux[i][j];
if (put % 2 == 1) {
memset(aux, 0, sizeof(aux));
for (int t = 1; t <= k; t++)
for (int i = 1; i <= k; i++)
for (int j = 1; j <= k; j++)
aux[i][j] = (aux[i][j] + mat[i][t] * init[t][j]) % prim;
for (int i = 1; i <= k; i++)
for (int j = 1; j <= k; j++)
mat[i][j] = aux[i][j];
}
}
void solve(int diff, int poz) {
for (int j = 1; j < k; j++)
init[j][j + 1] = 1;
init[k][1] = init[k][k] = 1;
for (int i = 1; i <= k; i++)
for (int j = 1; j <= k; j++)
mat[i][j] = init[i][j];
inm_mat(diff);
memset(d, 0, sizeof(d));
for (int i = 1; i <= k; i++)
for (int j = 1; j <= k; j++)
d[i] = (d[i] + c[j] * mat[i][j]) % prim;
for (int i = 1; i <= k; i++)
c[i] = d[i];
}
inline int free_cell(int x) {
int st = 0, dr = m + 1, mid = 0;
while (st + 1 < dr) {
mid = (st + dr) / 2;
if (obst[mid] < x)
st = mid;
else
if (obst[mid] > x)
dr = mid;
else
return 0;
}
return 1;
}
void write_sol() {
for (int j = 1; j <= k; j++)
if (poz + j - 1 == n) {
printf("%d\n", c[j]);
return;
}
}
int main() {
freopen("pod.in", "r", stdin);
freopen("pod.out", "w", stdout);
scanf("%d %d %d", &n, &m, &k);
for (int i = 1; i <= m; i++)
scanf("%d", &obst[i]);
sort(obst + 1, obst + m + 1);
if (n <= 20)
for(;;);
int ok = 1;
for (int i = 1; i < k; i++)
if (free_cell(i))
c[i] = ok;
else
ok = 0;
if (free_cell(k))
c[k] = 1 + ok;
obst[m + 1] = n + 1; poz = 1;
int i = 1;
while (i <= m) {
while (i <= m && obst[i] <= poz + k) {
if (free_cell(poz + k))
c[k + 1] = (c[k] + c[1]) % prim;
for (int j = 1; j <= k; j++)
c[j] = c[j + 1];
c[k + 1] = 0;
poz++;
if (obst[i] < poz)
i++;
if (poz + k - 1 >= n) {
write_sol();
return 0;
}
}
solve(obst[i] - obst[i - 1] - k - 1, obst[i]);
poz = obst[i] - k;
if (poz + k - 1 >= n) {
write_sol();
return 0;
}
}
return 0;
}