Cod sursa(job #2661183)

Utilizator PatrickCplusplusPatrick Kristian Ondreovici PatrickCplusplus Data 21 octombrie 2020 16:02:29
Problema Pod Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.17 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("pod.in");
ofstream fout("pod.out");

const int kmax = 30, mmax = 1005, mod = 9901;
int n, m, k, dp[kmax], v[mmax], a[kmax][kmax], sol[kmax][kmax], tmp[kmax][kmax], dp2[kmax];

void mult(int a[][kmax], int b[][kmax]){
    memset(tmp, 0, sizeof tmp);
    for (int i = 1; i <= k; ++i){
        for (int j = 1; j <= k; ++j){
            for (int l = 1; l <= k; ++l){
                tmp[i][j] += (a[i][l] * b[l][j]);
            }
        }
    }
    for (int i = 1; i <= k; ++i){
        for (int j = 1; j <= k; ++j){
            a[i][j] = tmp[i][j] % mod;
        }
    }
}

void mult2(){
    memset(dp2, 0, sizeof dp2);
    for (int i = 1; i <= 1; ++i){
        for (int j = 1; j <= k; ++j){
            for (int l = 1; l <= k; ++l){
                dp2[j] += dp[l] * sol[l][j];
            }
        }
    }
    for (int i = 1; i <= k; ++i){
        dp[i] = dp2[i] % mod;
    }
}

void log2pow(int p){
    while (p){
        if (p & 1)
            mult(sol, a);
        mult(a, a);
        p >>= 1;
    }
}


int main(){
    fin >> n >> m >> k;
    for (int i = 1; i <= m; ++i){
        fin >> v[i];
    }
    sort(v + 1, v + m + 1);
    v[m + 1] = n;
    dp[1] = 1;
    int j = 1;
    for (int i = 2; i <= k; ++i){
        if (j <= m && i - 1 == v[j]){
            dp[i] = 0;
            ++j;
        }
        else{
            dp[i] = dp[i - 1];
        }
    }
    v[j - 1] = k - 1;
    if (n <= k - 1){
        fout << v[n + 1];
        return 0;
    }
    while (j <= m){
        int p = v[j] - v[j - 1];
        memset(a, 0, sizeof a);
        memset(sol, 0, sizeof sol);
        a[1][k] = a[k][k] = sol[1][1] = 1;
        for (int i = 2; i <= k; ++i){
            a[i][i - 1] = sol[i][i] = 1;
        }
        log2pow(p);
        mult2();
        dp[k] = 0;
        ++j;
    }
    int p = n - v[j - 1];
    memset(sol, 0, sizeof sol);
    memset(a, 0, sizeof a);
    a[1][k] = a[k][k] = sol[1][1] = 1;
        for (int i = 2; i <= k; ++i){
            a[i][i - 1] = sol[i][i] = 1;
        }
    log2pow(p);
    mult2();
    fout << dp[k];
    return 0;
}