Problem p02808 (C++)

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

#define mod 1000000007
#define MAX_N 200010
long long inv[MAX_N];
long long factorial[MAX_N];
long long inv_factorial[MAX_N];

void GetInv() {
  for (int i = 1; i < MAX_N; i++) {
    if (i == 1)
      inv[i] = 1;
    else {
      inv[i] = (mod - (mod / i) * inv[mod % i]) % mod;
      if (inv[i] < 0)
        inv[i] += mod;
    }
  }
}
void GetFactorial() {
  factorial[0] = 1;
  inv_factorial[0] = 1;
  for (int i = 1; i < MAX_N; i++) {
    factorial[i] = factorial[i - 1] * i;
    factorial[i] %= mod;
    inv_factorial[i] = inv_factorial[i - 1] * inv[i];
    inv_factorial[i] %= mod;
  }
}

long long combination(int n, int r) {
  if (n < 0 || r < 0 || n < r)
    return 0;
  long long ret = factorial[n] * inv_factorial[r];
  ret %= mod;
  ret *= inv_factorial[n - r];
  return ret % mod;
}

long long modpow(int n, int r) {
  long long ret = 1;
  long long tmp = (long long)n;
  while (r != 0) {
    if (r % 2)
      ret *= tmp;
    tmp *= tmp;
    tmp %= mod;
    ret %= mod;
    r /= 2;
  }
  return ret;
}

long long dp[21][1010];

int main() {
  GetInv();
  GetFactorial();
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  int n, k;
  cin >> n >> k;
  vector<int> a(n);
  for (int i = 0; i < k; i++)
    cin >> a[i];
  dp[0][n] = 1;
  for (int i = 0; i < k; i++) {
    for (int j = 0; j <= n; j++) {
      for (int k = 0; k <= j; k++) {
        dp[i + 1][j - k] += dp[i][j] * combination(n - k, a[i] - k) % mod *
                            inv_factorial[k] % mod;
        dp[i + 1][j - k] %= mod;
      }
    }
  }
  cout << dp[k][0] * factorial[n] % mod << "\n";
  return 0;
}

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

#define mod 1000000007
#define MAX_N 200010
long long inv[MAX_N];
long long factorial[MAX_N];
long long inv_factorial[MAX_N];

void GetInv() {
  for (int i = 1; i < MAX_N; i++) {
    if (i == 1)
      inv[i] = 1;
    else {
      inv[i] = (mod - (mod / i) * inv[mod % i]) % mod;
      if (inv[i] < 0)
        inv[i] += mod;
    }
  }
}
void GetFactorial() {
  factorial[0] = 1;
  inv_factorial[0] = 1;
  for (int i = 1; i < MAX_N; i++) {
    factorial[i] = factorial[i - 1] * i;
    factorial[i] %= mod;
    inv_factorial[i] = inv_factorial[i - 1] * inv[i];
    inv_factorial[i] %= mod;
  }
}

long long combination(int n, int r) {
  if (n < 0 || r < 0 || n < r)
    return 0;
  long long ret = factorial[n] * inv_factorial[r];
  ret %= mod;
  ret *= inv_factorial[n - r];
  return ret % mod;
}

long long modpow(int n, int r) {
  long long ret = 1;
  long long tmp = (long long)n;
  while (r != 0) {
    if (r % 2)
      ret *= tmp;
    tmp *= tmp;
    tmp %= mod;
    ret %= mod;
    r /= 2;
  }
  return ret;
}

long long dp[21][1010];

int main() {
  GetInv();
  GetFactorial();
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  int n, k;
  cin >> n >> k;
  vector<int> a(k);
  for (int i = 0; i < k; i++)
    cin >> a[i];
  dp[0][n] = 1;
  for (int i = 0; i < k; i++) {
    for (int j = 0; j <= n; j++) {
      for (int k = 0; k <= j; k++) {
        dp[i + 1][j - k] += dp[i][j] * combination(n - k, a[i] - k) % mod *
                            inv_factorial[k] % mod;
        dp[i + 1][j - k] %= mod;
      }
    }
  }
  cout << dp[k][0] * factorial[n] % mod << "\n";
  return 0;
}