Pagini recente » Cod sursa (job #1320161) | Cod sursa (job #1937818) | Cod sursa (job #2104130) | Cod sursa (job #1733557) | Cod sursa (job #2240394)
#include <algorithm>
#include <fstream>
#include <cstring>
using namespace std;
ifstream fi("pod.in");
ofstream fo("pod.out");
const int N = 1e9 + 5, M = 1005, K = 25, MOD = 9901;
int n, m, k;
int planks[M], plank[K], trans[K][K], resmx[K][K], tempmx[K][K], pow2mx[K][K];
static void update_plank() {
static int new_plank[K];
memset(new_plank, 0x00, sizeof new_plank);
for (int i = 0; i <= k; ++i)
for (int j = 0; j <= k; ++j)
new_plank[i]+= resmx[i][j] * plank[j];
for (int i = 0; i <= k; ++i)
new_plank[i]%= MOD;
memcpy(plank, new_plank, sizeof plank); }
static void mult() {
memset(tempmx, 0x00, sizeof tempmx);
for (int i = 0; i <= k; ++i)
for (int j = 0; j <= k; ++j)
for (int p = 0; p <= k; ++p)
tempmx[i][j] = (tempmx[i][j] + resmx[i][p] * pow2mx[p][j]) % MOD;
memcpy(resmx, tempmx, sizeof tempmx); }
static void square() {
memset(tempmx, 0x00, sizeof tempmx);
for (int i = 0; i <= k; ++i)
for (int j = 0; j <= k; ++j)
for (int p = 0; p <= k; ++p)
tempmx[i][j] = (pow2mx[i][p] * pow2mx[p][j] + tempmx[i][j]) % MOD;
memcpy(pow2mx, tempmx, sizeof tempmx); }
static void update_matrix(int pwr) {
memcpy(pow2mx, trans, sizeof trans);
for (int i = 0; i <= k; ++i)
for (int j = 0; j <= k; ++j)
resmx[i][j] = int(i == j);
for (int lg = 0; (1 << lg) <= pwr; ++lg) {
if (pwr & (1 << lg))
mult();
square(); } }
int main() {
int lim, ptr = 0;
fi >> n >> m >> k;
for (int i = 0; i < m; ++i)
fi >> planks[i];
sort(planks, planks + m);
for (int i = m; i < M; ++i)
planks[i] = n + 1;
for (int i = 0; i < k; ++i) { // init plank
if (planks[ptr] == i) {
ptr++;
break; }
plank[i] = 1; }
while (planks[ptr] <= k)
++ptr;
if (k == 0 || planks[k - 1] != k)
plank[k] = plank[k - 1] + plank[0];
if (k == 1) {
fo << (m == 0 ? 1 : 0) << endl;
return 0; }
if (n <= k) {
fo << plank[n] << endl;
return 0; }
for (int i = 0; i < k; ++i) // init trans matrix
trans[i][i + 1] = 1;
trans[k][1] = trans[k][k] = 1;
lim = k;
do {
update_matrix(planks[ptr] - lim - 1);
update_plank();
lim = planks[ptr++];
for (int i = 0; i < k; ++i)
plank[i] = plank[i + 1];
plank[k] = 0; }
while (ptr <= m);
fo << plank[k - 1] << endl;
return 0; }