Cod sursa(job #1795288)

Utilizator TimitocArdelean Andrei Timotei Timitoc Data 2 noiembrie 2016 10:27:39
Problema Pod Scor 95
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.76 kb
#include <iostream>
#include <cstdio>
#include <algorithm>
#define MAXM 1050
#define MAXK 25
#define MOD 9901

using namespace std;

int ms[MAXM];

struct matrix
{
    int L, C;
    int v[MAXK][MAXK];
};

void mult(const matrix &a, const matrix &b, matrix &r)
{
    matrix rez;
    rez.L = a.L, rez.C = b.C;
    for (int i = 1; i <= rez.L; i++)
        for (int j = 1; j <= rez.C; j++)
            rez.v[i][j] = 0;
    for (int i = 1; i <= rez.L; i++)
        for (int j = 1; j <= rez.C; j++) {
            for (int k = 1; k <= a.C; k++)
                rez.v[i][j] = (rez.v[i][j] + a.v[i][k] * b.v[k][j]);
            rez.v[i][j] %= MOD;
        }
    r = rez;
}

void rise(const matrix &e, int p, matrix &rez)
{
    rez.L = e.L, rez.C = e.C;
    for (int i = 1; i <= rez.L; i++)
        for (int j = 1; j <= rez.C; j++)
            rez.v[i][j] = (i==j) ? 1 : 0;
    matrix duc = e;
    for (int i = 0; p >> i; i++) {
        if ((p>>i) & 1)
            mult(duc, rez, rez);
        mult(duc, duc, duc);
    }
}

int n, m, k;
matrix crt, fact, temp;
void solve()
{
    fact.L = fact.C = k;
    for (int i = 1; i < k; i++)
        fact.v[i][i+1] = 1;
    fact.v[k][k] = fact.v[k][1] = 1;
    crt.L = k; crt.C = 1;
    crt.v[k][1] = 1;
    for (int i = 1; i <= m; i++) {
        rise(fact, ms[i]-ms[i-1], temp);
        mult(temp, crt, crt);
        crt.v[k][1] = 0;
    }
    rise(fact, n-ms[m], temp);
    mult(temp, crt, crt);
    printf("%d", crt.v[k][1]);
}

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", &ms[i]);
    sort(ms+1, ms+m+1);
    if (ms[m] != n)
        solve();

    return 0;
}