Cod sursa(job #2242082)

Utilizator cristina_borzaCristina Borza cristina_borza Data 17 septembrie 2018 19:02:35
Problema Pod Scor 75
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.12 kb
#include <bits/stdc++.h>

using namespace std;

ifstream f ("pod.in");
ofstream g ("pod.out");

const int Mod = 9901;

int aux[25][25], ans[25][25], p[25][25];
int pos[1005], dp[25];
int n, m, k;

void BuildMatrix () {
    memset (p, 0, sizeof (p));
    for (int i = 1; i < k; ++ i) {
        p[i + 1][i] = 1;
    }

    p[1][k] = 1;
    p[k][k] = 1;
}

void Inmult () {
    for (int j = 1; j <= k; ++ j) {
        for (int l = 1; l <= k; ++ l) {
            aux[1][j] += (ans[1][l] * p[l][j]);
            aux[1][j] %= Mod;
        }
    }

    for (int i = 1; i <= k; ++ i) {
        for (int j = 1; j <= k; ++ j) {
            ans[i][j] = aux[i][j];
            aux[i][j] = 0;
        }
    }
}

void Ridica () {
    for (int i = 1; i <= k; ++ i) {
        for (int j = 1; j <= k; ++ j) {
            for (int l = 1; l <= k; ++ l) {
                aux[i][j] += (p[i][l] * p[l][j]);
                aux[i][j] %= Mod;
            }
        }
    }

    for (int i = 1; i <= k; ++ i) {
        for (int j = 1; j <= k; ++ j) {
            p[i][j] = aux[i][j];
            aux[i][j] = 0;
        }
    }
}

void Solve (int put) {
    BuildMatrix ();
    while (put) {
        if (put % 2 == 1) {
            Inmult ();
            --put;
        }

        else {
            Ridica ();
            put /= 2;
        }
    }
}

int main() {
    f >> n >> m >> k;
    for (int i = 1; i <= m; ++ i) {
        f >> pos[i];
    }

    sort (pos + 1, pos + m + 1);
    ans[1][1] = 1;

    for (int i = 1; i <= k; ++ i) {
        bool ok = true;
        for (int j = 1; j <= m; ++ j) {
            if (pos[j] == i) {
                ok = false;
                break;
            }

            if (pos[j] > i)
                break;
        }

        if (ok) ans[1][i + 1] = ans[1][i];
    }

    int lst = k - 1;
    for (int i = 1; i <= m; ++ i) {
        if (pos[i] <= lst)
            continue;


        Solve (pos[i] - lst); ans[1][k] = 0;
        lst = pos[i];
    }

    if (pos[m] < n)
        Solve (n - pos[m]);

    g << ans[1][k] << '\n';
    return 0;
}