Problem p01053 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <algorithm>
#include <array>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <valarray>
#include <vector>

using namespace std;
typedef long long ll;

const ll MD = 1e9 + 7;
const int MN = 5050;

int n, k, f;
ll fact[MN];
ll x[MN];
int dp[MN][MN], sm[MN][MN];
void init() {
  f = n / (2 * k);
  fact[0] = 1;
  for (int i = 1; i < MN; i++) {
    fact[i] = fact[i - 1] * f;
    fact[i] %= MD;
  }
  dp[0][0] = 1;
  for (int j = 1; j <= 2 * k; j++) {
    ll s = sm[0][j - 1];
    s += dp[0][j - 1];
    s %= MD;
    sm[0][j] = s;
    //		sm[0][j] = sm[0][j-1] + dp[0][j-1];
  }
  for (int i = 1; i < MN; i++) {
    for (int j = 0; j < k; j++) {
      ll s = sm[i - 1][j + 1];
      s += sm[i - 1][2 * k];
      s -= sm[i - 1][j + k + 1];
      s %= MD;
      s = (s + MD) % MD;
      dp[i][j] = s;
      //			dp[i][j] = sm[i-1][j+1] + sm[i-1][2*k] -
      //sm[i-1][j+k+1];
    }
    for (int j = k; j < 2 * k; j++) {
      ll s = sm[i - 1][j + 1];
      s -= sm[i - 1][j - k + 1];
      s %= MD;
      s = (s + MD) % MD;
      dp[i][j] = s;
      //			dp[i][j] = sm[i-1][j+1] -
      //sm[i-1][j-k+1];//dp[i-1][j]+dp[i-1][j-1]+dp[i-1][j-2]..dp[i-1][j-k+1]
    }
    for (int j = 1; j <= 2 * k; j++) {
      ll s = sm[i][j - 1];
      s += dp[i][j - 1];
      s %= MD;
      s = (s + MD) % MD;
      sm[i][j] = s;
      //			sm[i][j] = sm[i][j-1] + dp[i][j-1];
    }
  }
}

int main() {
  int m, q;
  cin >> n >> m >> k >> q;
  init();
  for (int i = 0; i < q; i++) {
    int a, b, c;
    cin >> a >> b >> c;
    c = (c - a + n) % n;
    if (b == 0) {
      if (c == 0) {
        printf("1\\n");
      } else {
        printf("0\\n");
      }
      continue;
    }
    c %= 2 * k;
    printf("%lld\\n", fact[b - 1] * dp[b][c] % MD);
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <array>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <valarray>
#include <vector>

using namespace std;
typedef long long ll;

const ll MD = 1e9 + 7;
const int MN = 5050;

int n, k, f;
ll fact[MN];
ll x[MN];
ll dp[MN][MN], sm[MN][MN];
void init() {
  f = n / (2 * k);
  fact[0] = 1;
  for (int i = 1; i < MN; i++) {
    fact[i] = fact[i - 1] * f;
    fact[i] %= MD;
  }
  dp[0][0] = 1;
  for (int j = 1; j <= 2 * k; j++) {
    sm[0][j] = sm[0][j - 1] + dp[0][j - 1];
  }
  for (int i = 1; i < MN; i++) {
    for (int j = 0; j < k; j++) {
      dp[i][j] = sm[i - 1][j + 1] + sm[i - 1][2 * k] - sm[i - 1][j + k + 1];
    }
    for (int j = k; j < 2 * k; j++) {
      dp[i][j] =
          sm[i - 1][j + 1] -
          sm[i - 1]
            [j - k + 1]; // dp[i-1][j]+dp[i-1][j-1]+dp[i-1][j-2]..dp[i-1][j-k+1]
    }
    for (int j = 1; j <= 2 * k; j++) {
      sm[i][j] = sm[i][j - 1] + dp[i][j - 1];
    }
  }
}

int main() {
  int m, q;
  cin >> n >> m >> k >> q;
  init();
  for (int i = 0; i < q; i++) {
    int a, b, c;
    cin >> a >> b >> c;
    c = (c - a + n) % n;
    if (b == 0) {
      if (a == c) {
        printf("1\\n");
      } else {
        printf("0\\n");
      }
      continue;
    }
    c %= 2 * k;
    printf("%lld\\n", fact[b - 1] * dp[b][c] % MD);
  }
  return 0;
}