Cod sursa(job #2241049)

Utilizator PopoviciRobertPopovici Robert PopoviciRobert Data 14 septembrie 2018 18:15:20
Problema Pod Scor 15
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.21 kb
#include <bits/stdc++.h>

using namespace std;

const int MOD = 9901;
const int MAXM = 1000;
const int MAXK = 20;

inline void mod(int &x) {
    if(x < 0)
        x += MOD;
    if(x >= MOD)
        x -= MOD;
}

int dp1[MAXM + 1], dp2[MAXM + 1], k;
int pos[MAXM + 1];

int a[MAXK + 1][MAXK + 1], ans[MAXK + 1][MAXK + 1];
int ways[MAXK + 1];

inline void multiply(int a[MAXK + 1][MAXK + 1], int b[MAXK + 1][MAXK + 1]) {
    int c[MAXK + 1][MAXK + 1];
    for(int i = 1; i <= k; i++) {
        for(int j = 1; j <= k; j++) {
            c[i][j] = 0;
            for(int p = 1; p <= k; p++) {
                c[i][j] = (c[i][j] + a[i][p] * b[p][j]) % MOD;
            }
        }
    }
    for(int i = 1; i <= k; i++) {
        for(int j = 1; j <= k; j++) {
            a[i][j] = c[i][j];
        }
    }
}

inline void lgput(int b) {
    while(b > 0) {
        if(b & 1)
            multiply(ans, a);
        b >>= 1;
        multiply(a, a);
    }
}

inline int get(int dst) {
    int i, j;
    if(dst <= k) {
        return ways[dst];
    }
    memset(a, 0, sizeof(a));
    for(i = 1; i < k; i++) {
        a[i + 1][i] = 1;
    }
    a[1][k] = 1;
    a[k][k] = 1;
    memset(ans, 0, sizeof(ans));
    for(i = 1; i <= k; i++) {
        ans[i][i] = 1;
    }
    lgput(dst - k);
    int sol = 0;
    for(i = 1; i <= k; i++) {
        sol = (sol + ways[i] * ans[i][k]) % MOD;
    }
    return sol;
}

int main() {
    FILE *fi, *fout;
    int i, j, n, m;
    fi = fopen("pod.in" ,"r");
    fout = fopen("pod.out" ,"w");
    fscanf(fi,"%d %d %d " ,&n,&m,&k);
    for(i = 1; i <= m; i++) {
        fscanf(fi,"%d " ,&pos[i]);
    }
    sort(pos + 1, pos + m + 1);
    ways[0] = 1;
    for(i = 1; i <= k; i++) {
        ways[i] = ways[i - 1];
    }
    ways[k]++;
    for(i = m; i >= 1; i--) {
        dp2[i] = get(n - pos[i]);
        for(j = i + 1; j <= m; j++) {
            dp2[i] -= (dp2[j] * get(pos[j] - pos[i])) % MOD;
            mod(dp2[i]);
        }
    }
    int ans = get(n);
    for(i = 1; i <= m; i++) {
        ans -= (get(pos[i]) * dp2[i]) % MOD;
        mod(ans);
    }
    fprintf(fout,"%d" ,ans);
    fclose(fi);
    fclose(fout);
    return 0;
}