Cod sursa(job #945091)

Utilizator SRaduRadu Szasz SRadu Data 30 aprilie 2013 15:17:29
Problema Pod Scor 75
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.94 kb
#include <fstream>
#include <cstring>
#include <algorithm>

#define KMAX 22
#define MAX 1005
#define REST 9901

using namespace std;

int N, M, K;
int V[MAX], ans[KMAX], ANS[KMAX], dp[KMAX][KMAX], aux[KMAX][KMAX];

void citire() {
    ifstream in("pod.in");
    in>>N>>M>>K;
    for(int i = 1; i <= M; i++) in >> V[i];
    V[++M] = N; sort(V + 1, V + M + 1);
    in.close();
}

void init() {
    for(int i = 1; i < K; i++)
        dp[i + 1][i] = 1;
    dp[K][K] = dp[1][K] = 1;
}

void mul(int rez[KMAX][KMAX], int A[KMAX][KMAX], int B[KMAX][KMAX]) {
    for(int i = 1; i <= K; i++)
        for(int j = 1; j <= K; j++)
            for(int k = 1; k <= K; k++) {
                rez[i][j] += A[i][k] * B[k][j];
                if(rez[i][j] >= REST) rez[i][j] %= REST;
            }
}

void lgput(int rez[KMAX][KMAX], int A[KMAX][KMAX], int put) {
    int B[KMAX][KMAX], aux[KMAX][KMAX];
    memset(aux, 0, sizeof(aux));
    memcpy(B, A, sizeof(B));
    for(int i = 1; i <= K; i++) rez[i][i] = 1;
    for(; put; put >>= 1) {
        if(put & 1) {
            memset(aux, 0, sizeof(aux));
            mul(aux, rez, B);
            memcpy(rez, aux, sizeof(aux));
        }
        memset(aux, 0, sizeof(aux));
        mul(aux, B, B);
        memcpy(B, aux, sizeof(aux));
    }
}

void solve() {
    init();
    ans[K] = 1;
    for(int i = 1; i <= M; i++) {
        memset(aux, 0, sizeof(aux));
        memset(ANS, 0, sizeof(ANS));
        lgput(aux, dp, V[i] - V[i - 1]);
        for(int j = 1; j <= K; j++)
            for(int k = 1; k <= K; k++) {
                ANS[j] += aux[j][k] * ans[k];
                if(ANS[j] >= REST) ANS[j] %= REST;
            }
        if(i < M) ANS[K] = 0;
        for(int j = 1; j <= K; j++) ans[j] = ANS[j];
    }
}

void afisare() {
    ofstream out("pod.out");
    out<<ans[K]<<"\n";
    out.close();
}

int main() {
    citire();
    solve();
    afisare();
    return 0;
}