Problem p01944 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

typedef vector<ll> V;
typedef vector<V> MATRIX;

int N, M;
ll table[10000];

MATRIX calc_ans(MATRIX left, MATRIX right) {
  MATRIX RET(1, V(N));
  for (int col = 0; col < N; col++) {
    RET[0][col] = 0;
    for (int row = 0; row < N; row++) {
      RET[0][col] += left[0][row] * right[row][col];
      RET[0][col] %= MOD;
    }
  }

  return RET;
}

MATRIX calc(MATRIX left, MATRIX right) {

  MATRIX ret(N, V(N));

  for (int i = 0; i < N; i++) {
    for (int k = 0; k < N; k++)
      ret[i][k] = 0;
  }

  for (int col = 0; col < N; col++) {
    ret[0][col] = 0;
    for (int row = 0; row < N; row++) {
      ret[0][col] += left[0][row] * right[row][col];
      ret[0][col] %= MOD;
    }
  }

  for (int row = 0; row <= N - 2; row++) {
    for (int col = 0; col <= N - 1; col++) {
      ret[row + 1][(col + 1) % N] = ret[row][col];
    }
  }

  return ret;
}

MATRIX pow(MATRIX MULT, int count) {

  MATRIX ret(N, V(N));

  for (int row = 0; row < N; row++) {
    for (int col = 0; col < N; col++) {
      if (row == col)
        ret[row][col] = 1;
      else {
        ret[row][col] = 0;
      }
    }
  }

  while (count > 0) {
    if (count % 2 == 1)
      ret = calc(ret, MULT);
    MULT = calc(MULT, MULT);
    count /= 2;
  }

  return ret;
}

int main() {

  int K;
  scanf("%d %d %d", &N, &M, &K);

  for (int i = 0; i < M; i++) {
    scanf("%lld", &table[i]);
    table[i] %= N;
  }

  ll work[N];
  work[0] = 1;
  for (int i = 1; i <= N - 1; i++)
    work[i] = 0;

  for (int i = 0; i < M; i++) {
    work[table[i]]++;
  }

  MATRIX first_state(1, V(N));
  first_state[0][0] = 1;

  for (int i = 1; i <= N - 1; i++)
    first_state[0][i] = 0;

  MATRIX transition(N, V(N));
  for (int i = 0; i <= N - 1; i++)
    transition[0][i] = work[i];

  for (int row = 0; row <= N - 2; row++) {
    for (int col = 0; col <= N - 1; col++) {
      transition[row + 1][(col + 1) % N] = transition[row][col];
    }
  }

  if (K > 1) {
    transition = pow(transition, K);
  }

  MATRIX ans = calc_ans(first_state, transition);

  for (int i = 0; i < N; i++) {
    printf("%lld\\n", ans[0][i] % MOD);
  }

  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

typedef vector<ll> V;
typedef vector<V> MATRIX;

int N, M;
ll table[10000];

MATRIX calc_ans(MATRIX left, MATRIX right) {
  MATRIX RET(1, V(N));
  for (int col = 0; col < N; col++) {
    RET[0][col] = 0;
    for (int row = 0; row < N; row++) {
      RET[0][col] += left[0][row] * right[row][col];
      RET[0][col] %= MOD;
    }
  }

  return RET;
}

MATRIX calc(MATRIX left, MATRIX right) {

  MATRIX ret(N, V(N));

  for (int i = 0; i < N; i++) {
    for (int k = 0; k < N; k++)
      ret[i][k] = 0;
  }

  for (int row = 0; row < N; row++) {
    for (int col = 0; col < N; col++) {
      for (int a = 0; a < N; a++) {
        ret[row][col] += left[row][a] * right[a][col];
        ret[row][col] %= MOD;
      }
    }
  }

  return ret;
}

MATRIX pow(MATRIX MULT, int count) {

  MATRIX ret(N, V(N));

  for (int row = 0; row < N; row++) {
    for (int col = 0; col < N; col++) {
      if (row == col)
        ret[row][col] = 1;
      else {
        ret[row][col] = 0;
      }
    }
  }

  while (count > 0) {
    if (count % 2 == 1)
      ret = calc(ret, MULT);
    MULT = calc(MULT, MULT);
    count /= 2;
  }

  return ret;
}

int main() {

  int K;
  scanf("%d %d %d", &N, &M, &K);

  for (int i = 0; i < M; i++) {
    scanf("%lld", &table[i]);
    table[i] %= N;
  }

  ll work[N];
  work[0] = 1;
  for (int i = 1; i <= N - 1; i++)
    work[i] = 0;

  for (int i = 0; i < M; i++) {
    work[table[i]]++;
  }

  MATRIX first_state(1, V(N));
  first_state[0][0] = 1;

  for (int i = 1; i <= N - 1; i++)
    first_state[0][i] = 0;

  MATRIX transition(N, V(N));
  for (int i = 0; i <= N - 1; i++)
    transition[0][i] = work[i];

  for (int row = 0; row <= N - 2; row++) {
    for (int col = 0; col <= N - 1; col++) {
      transition[row + 1][(col + 1) % N] = transition[row][col];
    }
  }

  if (K > 1) {
    transition = pow(transition, K);
  }

  MATRIX ans = calc_ans(first_state, transition);

  for (int i = 0; i < N; i++) {
    printf("%lld\\n", ans[0][i] % MOD);
  }

  return 0;
}