Problem p04004 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <ciso646>
#include <cmath>
#include <complex>
#include <cstdio>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 1000000007;
typedef long double ld;
typedef complex<ld> Point;
const ll INF = mod * mod;
typedef pair<int, int> P;
#define stop                                                                   \
  char nyaa;                                                                   \
  cin >> nyaa;
#define rep(i, n) for (int i = 0; i < n; i++)
#define per(i, n) for (int i = n - 1; i >= 0; i--)
#define Rep(i, sta, n) for (int i = sta; i < n; i++)
#define rep1(i, n) for (int i = 1; i <= n; i++)
#define per1(i, n) for (int i = n; i >= 1; i--)
#define Rep1(i, sta, n) for (int i = sta; i <= n; i++)
const ld eps = 1e-6;
const ld pi = acos(-1.0);
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;

struct perm {
private:
  int sz;
  vector<ll> p, invp;

public:
  perm(int n) {
    sz = n + 1;
    p.resize(sz), invp.resize(sz);
    p[0] = 1;
    rep1(i, sz - 1) { p[i] = p[i - 1] * i % mod; }
    invp[sz - 1] = 1;
    ll cop = mod - 2, x = p[sz - 1];
    while (cop) {
      if (cop % 2)
        invp[sz - 1] = invp[sz - 1] * x % mod;
      cop >>= 1;
      x = x * x % mod;
    }
    per(i, sz - 1) { invp[i] = invp[i + 1] * (i + 1) % mod; }
  }
  ll comb(ll x, ll y) {
    if (x < y || y < 0)
      return 0;
    ll ret = p[x];
    (ret *= invp[y]) %= mod;
    (ret *= invp[x - y]) %= mod;
    return ret;
  }
  ll combP(ll x, ll y) {
    if (x < y || y < 0)
      return 0;
    return p[x] * invp[x - y] % mod;
  }
};
perm p(1 << 19);

ll t3[700001];

void solve() {
  t3[0] = 1;
  rep(i, 700000) t3[i + 1] = t3[i] * 3 % mod;
  int n, m, k;
  cin >> n >> m >> k;
  ll ans = 0;
  ll cur = 0;
  rep(t, m + k + 1) {
    ll csum = p.comb(t + n - 1, t) * t3[m + k - t] % mod;
    ll ncur = 0;
    if (t == 0) {
      cur = 1;
    } else {
      int ple = max(t - 1 - k, 0);
      int pri = min(m, t - 1);
      int le = max(t - k, 0);
      int ri = min(m, t);
      ncur += cur;
      cur += mod - p.comb(t - 1, ple);
      cur += p.comb(t - 1, pri + 1);
      if (le == ple)
        cur++;
      if (pri == ri) {
        // cur += mod - 1;
        cur += mod - p.comb(t - 1, pri);
        cur += mod - p.comb(t - 1, pri + 1);
      }
      while (cur >= mod)
        cur -= mod;
      ncur += cur;
      while (ncur >= mod)
        ncur -= mod;
      cur = ncur;
      // cout << t << " " << ncur << endl;
    }
    ans += cur * csum % mod;
    if (ans >= mod)
      ans -= mod;
    // cout << ans << endl;
  }
  cout << ans << endl;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  solve();
  // stop
  return 0;
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <ciso646>
#include <cmath>
#include <complex>
#include <cstdio>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 1000000007;
typedef long double ld;
typedef complex<ld> Point;
const ll INF = mod * mod;
typedef pair<int, int> P;
#define stop                                                                   \
  char nyaa;                                                                   \
  cin >> nyaa;
#define rep(i, n) for (int i = 0; i < n; i++)
#define per(i, n) for (int i = n - 1; i >= 0; i--)
#define Rep(i, sta, n) for (int i = sta; i < n; i++)
#define rep1(i, n) for (int i = 1; i <= n; i++)
#define per1(i, n) for (int i = n; i >= 1; i--)
#define Rep1(i, sta, n) for (int i = sta; i <= n; i++)
const ld eps = 1e-6;
const ld pi = acos(-1.0);
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;

struct perm {
private:
  int sz;
  vector<ll> p, invp;

public:
  perm(int n) {
    sz = n + 1;
    p.resize(sz), invp.resize(sz);
    p[0] = 1;
    rep1(i, sz - 1) { p[i] = p[i - 1] * i % mod; }
    invp[sz - 1] = 1;
    ll cop = mod - 2, x = p[sz - 1];
    while (cop) {
      if (cop % 2)
        invp[sz - 1] = invp[sz - 1] * x % mod;
      cop >>= 1;
      x = x * x % mod;
    }
    per(i, sz - 1) { invp[i] = invp[i + 1] * (i + 1) % mod; }
  }
  ll comb(ll x, ll y) {
    if (x < y || y < 0)
      return 0;
    ll ret = p[x];
    (ret *= invp[y]) %= mod;
    (ret *= invp[x - y]) %= mod;
    return ret;
  }
  ll combP(ll x, ll y) {
    if (x < y || y < 0)
      return 0;
    return p[x] * invp[x - y] % mod;
  }
};
perm p(1 << 20);

ll t3[700001];

void solve() {
  t3[0] = 1;
  rep(i, 700000) t3[i + 1] = t3[i] * 3 % mod;
  int n, m, k;
  cin >> n >> m >> k;
  ll ans = 0;
  ll cur = 0;
  rep(t, m + k + 1) {
    ll csum = p.comb(t + n - 1, t) * t3[m + k - t] % mod;
    ll ncur = 0;
    if (t == 0) {
      cur = 1;
    } else {
      int ple = max(t - 1 - k, 0);
      int pri = min(m, t - 1);
      int le = max(t - k, 0);
      int ri = min(m, t);
      ncur += cur;
      cur += mod - p.comb(t - 1, ple);
      cur += p.comb(t - 1, pri + 1);
      if (le == ple)
        cur++;
      if (pri == ri) {
        // cur += mod - 1;
        cur += mod - p.comb(t - 1, pri);
        cur += mod - p.comb(t - 1, pri + 1);
      }
      while (cur >= mod)
        cur -= mod;
      ncur += cur;
      while (ncur >= mod)
        ncur -= mod;
      cur = ncur;
      // cout << t << " " << ncur << endl;
    }
    ans += cur * csum % mod;
    if (ans >= mod)
      ans -= mod;
    // cout << ans << endl;
  }
  cout << ans << endl;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  solve();
  // stop
  return 0;
}