Cod sursa(job #2486121)

Utilizator popashtefan10Popa Stefan popashtefan10 Data 2 noiembrie 2019 12:32:39
Problema Pod Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.14 kb
#include <iostream>
#include <cstdio>
#include <algorithm>
#define MOD 9901

using namespace std;

int n, m, k, old_sc, new_sc;
int poz[1005], v[50];

struct matrice {
  int a[25][25];

  matrice() {
    for(int i = 0; i <= k + 2; i++)
      for(int j = 0; j <= k + 2; j++)
        a[i][j] = 0;
  }

  void afisare() {
    for(int i = 1; i <= k; i++) {
      for(int j = 1; j <= k; j++)
        printf("%d ", a[i][j]);
      printf("\n");
    }
  }

  matrice operator* (const matrice x) {
    matrice rez;

    for(int i = 1; i <= k; i++)
      for(int j = 1; j <= k; j++)
        for(int p = 1; p <= k; p++)
          rez.a[i][j] =  (rez.a[i][j] + (a[i][p] * x.a[p][j]) % MOD) % MOD;
    return rez;
  }

};

matrice getM() {
  matrice M;

  for(int i = 1; i < k; i++)
    M.a[i + 1][i] = 1;
  M.a[1][k] = M.a[k][k] = 1;

  return M;
}

matrice ide() {
  matrice x;

  for(int i = 1; i <= k; i++)
    x.a[i][i] = 1;
  return x;
}

void gen_firstk() {
  for(int i = k + 1; i <= 2 * k - 1; i++)
    v[i] = (v[i - 1] + v[i - k]) % MOD;
}

matrice fast_pow(matrice M, int pow) {
  matrice rez = ide();

  while(pow > 1) {
    if(pow % 2 == 1)
      rez = rez * M;
    M = M * M;
    pow /= 2;
  }
  return M * rez;
}

int main() {
  freopen("pod.in", "r", stdin);
  freopen("pod.out", "w", stdout);
  int dif;

  scanf("%d %d %d", &n, &m, &k);
  for(int i = 1; i <= m; i++)
    scanf("%d", &poz[i]);
  sort(poz + 1, poz + m + 1);
  poz[m + 1] = n + 1;

  v[k] = 1;
  gen_firstk();
  for(new_sc = 1; new_sc <= m + 1; new_sc++) {
    int dif = poz[new_sc] - poz[old_sc] - 1;

    if(dif <= k - 1) {
      v[k + dif + 1] = 0;
      for(int i = 1; i <= k; i++)
        v[i] = v[i + dif + 1];
    }
    else {
      v[k] = 0;
      matrice M = getM(), first = matrice();

      for(int i = k; i <= 2 * k - 1; i++)
        first.a[1][i - k + 1] = v[i];
      M = fast_pow(M, dif);
      first = first * M;
      for(int i = 1; i <= k - 1; i++)
        v[i] = first.a[1][i];
      v[k] = 0;
    }

    gen_firstk();
    old_sc = new_sc;
  }
  printf("%d", v[k - 1]);

  return 0;
}