Problem p04038 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

#define MAX 2002
#define MOD 1000000007

long long int dp[MAX][MAX];

#define MOD 1000000007
class Combination {
  long long int ppow(long long int i, long long int j) {
    long long int res = 1LL;
    while (j) {
      if ((j & 1LL)) {
        res *= i;
        if (res >= MOD) {
          res %= MOD;
        }
      }
      j >>= 1;
      i *= i;
      if (i >= MOD) {
        i %= MOD;
      }
    }
    return res;
  }

public:
  vector<long long int> k;
  vector<long long int> r;
  void resize(int N) {
    k.resize(N + 2);
    r.resize(N + 2);
    k[0] = 1;
    for (int i = 1; i < k.size(); i++) {
      k[i] = k[i - 1];
      k[i] *= i;
      if (k[i] >= MOD)
        k[i] %= MOD;
    }
    for (int i = 0; i < r.size(); i++) {
      r[i] = ppow(k[i], MOD - 2);
    }
  }
  long long int C(int a, int b) {
    if (a < b)
      return 0;
    while (k.size() <= a) {
      k.push_back((k.back() * (long long int)(k.size())) % MOD);
    }
    long long int up = k[a];
    long long int dw = r[b] * r[a - b];
    dw %= MOD;
    up *= dw;
    up %= MOD;
    return up;
  }
  long long int H(int a, int b) { return C(a + b - 1, b); }
  long long int catalan_number(int n) {
    return (C(2 * n, n) + MOD - C(2 * n, n - 1)) % MOD;
  }
};

Combination C;
int main() {
  int n;
  int k;
  cin >> n >> k;
  C.resize(2002);
  dp[0][0] = 1;
  if (k == 1) {
    puts("1");
    return 0;
  }
  for (int i = 0; i <= n; i++) {
    for (int j = 0; j <= n; j++) {
      dp[i + 1][j] += dp[i][j];
      if (dp[i + 1][j] >= MOD) {
        dp[i + 1][j] %= MOD;
      }
      if (j + 1 <= i) {
        dp[i][j + 1] +=
            dp[i][j] * C.C(n * k - ((k - 2) * j + j + i + 1), k - 2);
        if (dp[i][j + 1] >= MOD) {
          dp[i][j + 1] %= MOD;
        }
      }
    }
  }
  long long int ans = dp[n][n] * C.k[n];
  if (ans >= MOD)
    ans %= MOD;
  printf("%lld\n", ans);
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;

#define MAX 2002
#define MOD 1000000007

long long int dp[MAX][MAX];

#define MOD 1000000007
class Combination {
  long long int ppow(long long int i, long long int j) {
    long long int res = 1LL;
    while (j) {
      if ((j & 1LL)) {
        res *= i;
        if (res >= MOD) {
          res %= MOD;
        }
      }
      j >>= 1;
      i *= i;
      if (i >= MOD) {
        i %= MOD;
      }
    }
    return res;
  }

public:
  vector<long long int> k;
  vector<long long int> r;
  void resize(int N) {
    k.resize(N + 2);
    r.resize(N + 2);
    k[0] = 1;
    for (int i = 1; i < k.size(); i++) {
      k[i] = k[i - 1];
      k[i] *= i;
      if (k[i] >= MOD)
        k[i] %= MOD;
    }
    for (int i = 0; i < r.size(); i++) {
      r[i] = ppow(k[i], MOD - 2);
    }
  }
  long long int C(int a, int b) {
    if (a < b)
      return 0;
    while (k.size() <= a) {
      k.push_back((k.back() * (long long int)(k.size())) % MOD);
    }
    long long int up = k[a];
    long long int dw = r[b] * r[a - b];
    dw %= MOD;
    up *= dw;
    up %= MOD;
    return up;
  }
  long long int H(int a, int b) { return C(a + b - 1, b); }
  long long int catalan_number(int n) {
    return (C(2 * n, n) + MOD - C(2 * n, n - 1)) % MOD;
  }
};

Combination C;
int main() {
  int n;
  int k;
  cin >> n >> k;
  C.resize(2002 * 2002);
  dp[0][0] = 1;
  if (k == 1) {
    puts("1");
    return 0;
  }
  for (int i = 0; i <= n; i++) {
    for (int j = 0; j <= n; j++) {
      dp[i + 1][j] += dp[i][j];
      if (dp[i + 1][j] >= MOD) {
        dp[i + 1][j] %= MOD;
      }
      if (j + 1 <= i) {
        dp[i][j + 1] +=
            dp[i][j] * C.C(n * k - ((k - 2) * j + j + i + 1), k - 2);
        if (dp[i][j + 1] >= MOD) {
          dp[i][j + 1] %= MOD;
        }
      }
    }
  }
  long long int ans = dp[n][n] * C.k[n];
  if (ans >= MOD)
    ans %= MOD;
  printf("%lld\n", ans);
  return 0;
}