Problem p02654 (C++) — buggy submission, verdict: Runtime Error

// Awwawa! Dis cold yis ratten buy tEMMIE!
#include <bits/stdc++.h>
#define ll long long
#define maxn 10000005 /*rem*/
#define mod 1000000007
#define db double
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define pi pair<int, int>
#define fi first
#define se second

template <typename T> bool chkmax(T &x, T y) {
  return x < y ? x = y, true : false;
}
template <typename T> bool chkmin(T &x, T y) {
  return x > y ? x = y, true : false;
}

using namespace std;
ll ksm(ll a, ll b) {
  if (!b)
    return 1;
  ll ns = ksm(a, b >> 1);
  ns = ns * ns % mod;
  if (b & 1)
    ns = ns * a % mod;
  return ns;
}
int n, a;
ll jc[maxn], bjc[maxn];
ll bk[20005];
ll pr[5005];       // 恰有
ll tr[5005][5005]; // 有x个自环 钦定若干个不能是
ll c(int a, int b) {
  if (b > a || b < 0)
    return 0;
  return 1ll * jc[a] * bjc[b] % mod * bjc[a - b] % mod;
}
ll dp[5005][5005]; // 还剩若干个 要求若干个
ll s[5005][5005];
int main() {
  jc[0] = bjc[0] = 1;
  for (int i = 1; i < maxn; i++)
    jc[i] = jc[i - 1] * i % mod;
  bjc[maxn - 1] = ksm(jc[maxn - 1], mod - 2);
  for (int j = maxn - 2; j >= 0; j--)
    bjc[j] = bjc[j + 1] * (j + 1) % mod;
  for (int i = 0; i < 20005; i++)
    bk[i] = ksm(i, mod - 2);
  int n, k;
  cin >> n >> k;
  for (int i = 0; i < k; i++) {
    // 钦定i个数 假
    pr[i] = 1;
    pr[i] = pr[i] * jc[n - i - 1] % mod;
    pr[i] = pr[i] * bjc[k - i - 1] % mod;
  }
  for (int i = 0; i <= k; i++) // 有i个必须交互 j个数不能和后面交互
    for (int j = 0; j <= k - i; j++) {
      // 要求i不能是 j必须是
      ll er = 0;
      if (i == 0)
        er = pr[j];
      else {
        er = tr[i - 1][j] - tr[i - 1][j + 1];
        er %= mod;
        if (er < 0)
          er += mod;
      }
      tr[i][j] = er;
    }
  for (int i = 0; i <= k; i++)
    for (int j = 0; j <= k - i; j++) { // 有j个限制 剩余长度是i
      ll mt = bk[i];
      if (i == 0)
        mt = 1;
      dp[i][j] = tr[j][i] * mt % mod; // * bk[i] % mod; // 当前点要求是自环
      if (i)
        dp[i][j] +=
            (s[i - 1][j] - dp[i - 1][j] + dp[i - 1][j + 1]) % mod * bk[i] % mod;
      dp[i][j] %= mod;
      if (i)
        s[i][j] = s[i - 1][j];
      s[i][j] = (s[i][j] + dp[i][j]) % mod;
    }
  ll ans = dp[k][0];
  ans %= mod;
  ans = ans * jc[k] % mod;
  ans %= mod;
  if (ans < 0)
    ans += mod;
  cout << ans << endl;
  return 0;
}


Error: -11

Fixed submission:

// Awwawa! Dis cold yis ratten buy tEMMIE!
#include <bits/stdc++.h>
#define ll long long
#define maxn 10000005 /*rem*/
#define mod 1000000007
#define db double
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define pi pair<int, int>
#define fi first
#define se second

template <typename T> bool chkmax(T &x, T y) {
  return x < y ? x = y, true : false;
}
template <typename T> bool chkmin(T &x, T y) {
  return x > y ? x = y, true : false;
}

using namespace std;
ll ksm(ll a, ll b) {
  if (!b)
    return 1;
  ll ns = ksm(a, b >> 1);
  ns = ns * ns % mod;
  if (b & 1)
    ns = ns * a % mod;
  return ns;
}
int n, a;
ll jc[maxn], bjc[maxn];
ll bk[20005];
ll pr[5005];       // 恰有
ll tr[5005][5005]; // 有x个自环 钦定若干个不能是
ll c(int a, int b) {
  if (b > a || b < 0)
    return 0;
  return 1ll * jc[a] * bjc[b] % mod * bjc[a - b] % mod;
}
ll dp[5005][5005]; // 还剩若干个 要求若干个
ll r[5005];
ll s[5005][5005];
int main() {
  jc[0] = bjc[0] = 1;
  for (int i = 1; i < maxn; i++)
    jc[i] = jc[i - 1] * i % mod;
  bjc[maxn - 1] = ksm(jc[maxn - 1], mod - 2);
  for (int j = maxn - 2; j >= 0; j--)
    bjc[j] = bjc[j + 1] * (j + 1) % mod;
  for (int i = 0; i < 20005; i++)
    bk[i] = ksm(i, mod - 2);
  int n, k;
  cin >> n >> k;
  for (int i = 0; i < k; i++) {
    // 钦定i个数 假
    pr[i] = 1;
    pr[i] = pr[i] * jc[n - i - 1] % mod;
    pr[i] = pr[i] * bjc[k - i - 1] % mod;
  }
  for (int i = 0; i <= k; i++) // 有i个必须交互 j个数不能和后面交互
    for (int j = 0; j <= k - i; j++) {
      // 要求i不能是 j必须是
      ll er = 0;
      if (i == 0)
        er = pr[j];
      else {
        er = tr[i - 1][j] - tr[i - 1][j + 1];
        er %= mod;
        if (er < 0)
          er += mod;
      }
      tr[i][j] = er;
    }
  for (int i = 0; i <= k; i++)
    for (int j = 0; j <= k - i; j++) { // 有j个限制 剩余长度是i
      ll mt = bk[i];
      if (i == 0)
        mt = 1;
      dp[i][j] = tr[j][i] * mt % mod; // * bk[i] % mod; // 当前点要求是自环
      dp[i][j] +=
          (s[i - 1][j] - dp[i - 1][j] + dp[i - 1][j + 1]) % mod * bk[i] % mod;
      dp[i][j] %= mod;
      if (i)
        s[i][j] = s[i - 1][j];
      s[i][j] = (s[i][j] + dp[i][j]) % mod;
    }
  ll ans = dp[k][0];
  ans %= mod;
  ans = ans * jc[k] % mod;
  ans %= mod;
  if (ans < 0)
    ans += mod;
  cout << ans << endl;
  return 0;
}