Problem p03154 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <deque>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <time.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

typedef long long ll;

#ifdef ONPC
mt19937 rnd(228);
#else
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
#endif

const int N = 2e7 + 7;
const int M = 1e9 + 7;

inline int add(int a, int b) {
  a += b;
  if (a >= M)
    a -= M;
  return a;
}

inline int mul(int a, int b) { return (a * (ll)b) % M; }

inline int bin(int a, int n) {
  int res = 1;
  while (n) {
    if (n % 2 == 0) {
      a = mul(a, a);
      n /= 2;
    } else {
      res = mul(res, a);
      n--;
    }
  }
  return res;
}

inline int inv(int x) { return bin(x, M - 2); }

int dp[N][3];
int s[N][3];
int fact[N];
int rfact[N];

int odp[N][3];
int os[N][3];

int C(int n, int k) {
  if (n < k)
    return 0;
  return mul(fact[n], mul(rfact[k], rfact[n - k]));
}

int main() {
#ifdef ONPC
  freopen("a.in", "r", stdin);
#endif
  ios::sync_with_stdio(0);
  cin.tie(0);
  fact[0] = 1;
  for (int i = 1; i < N; i++) {
    fact[i] = mul(fact[i - 1], i);
  }
  for (int i = 0; i < N; i++) {
    rfact[i] = inv(fact[i]);
  }
  dp[0][0] = 1;
  for (int i = 0; i + 1 < N; i++) {
    for (int t = 0; t <= 2; t++) {
      if (t == 1) {
        os[i][t] = add(os[i][t], dp[i][t]);
      }
      if (t == 2) {
        s[i][t] = add(s[i][t], dp[i][t]);
      }
      for (int nt = t; nt <= 2 && nt <= t + 1; nt++) {
        os[i + 1][nt] = add(os[i + 1][nt], os[i][t]);
        s[i + 1][nt] = add(s[i + 1][nt], s[i][t]);
        dp[i + 1][nt] = add(dp[i + 1][nt], dp[i][t]);
      }
    }
  }
  int h, w, k;
  cin >> h >> w >> k;
  int ans = mul(k, mul(C(h + w, k), fact[k]));
  if (k >= 2) {
    int cur = mul(C(h + w - 2, k - 2), fact[k - 2]);
    cur = mul(cur, (h * (ll)w) % M);
    cur = mul(cur, mul(2, s[k][2]));
    ans = add(ans, cur);
  }
  if (k >= 1) {
    int cur = mul(C(h + w - 1, k - 1), fact[k - 1]);
    cur = mul(cur, h + w);
    cur = mul(cur, os[k][1]);
    ans = add(ans, cur);
  }
  cout << ans << '\n';
}


Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <deque>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <time.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

typedef long long ll;

#ifdef ONPC
mt19937 rnd(228);
#else
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
#endif

const int N = 2e7 + 7;
const int M = 1e9 + 7;

inline int add(int a, int b) {
  a += b;
  if (a >= M)
    a -= M;
  return a;
}

inline int mul(int a, int b) { return (a * (ll)b) % M; }

inline int bin(int a, int n) {
  int res = 1;
  while (n) {
    if (n % 2 == 0) {
      a = mul(a, a);
      n /= 2;
    } else {
      res = mul(res, a);
      n--;
    }
  }
  return res;
}

inline int inv(int x) { return bin(x, M - 2); }

int dp[N][3];
int s[N][3];
int fact[N];
int rfact[N];

int odp[N][3];
int os[N][3];

int C(int n, int k) {
  if (n < k)
    return 0;
  return mul(fact[n], mul(rfact[k], rfact[n - k]));
}

int main() {
#ifdef ONPC
  freopen("a.in", "r", stdin);
#endif
  ios::sync_with_stdio(0);
  cin.tie(0);
  fact[0] = 1;
  for (int i = 1; i < N; i++) {
    fact[i] = mul(fact[i - 1], i);
  }
  rfact[N - 1] = inv(fact[N - 1]);
  for (int i = N - 2; i >= 0; i--) {
    rfact[i] = mul(rfact[i + 1], i + 1);
  }
  dp[0][0] = 1;
  for (int i = 0; i + 1 < N; i++) {
    for (int t = 0; t <= 2; t++) {
      if (t == 1) {
        os[i][t] = add(os[i][t], dp[i][t]);
      }
      if (t == 2) {
        s[i][t] = add(s[i][t], dp[i][t]);
      }
      for (int nt = t; nt <= 2 && nt <= t + 1; nt++) {
        os[i + 1][nt] = add(os[i + 1][nt], os[i][t]);
        s[i + 1][nt] = add(s[i + 1][nt], s[i][t]);
        dp[i + 1][nt] = add(dp[i + 1][nt], dp[i][t]);
      }
    }
  }
  int h, w, k;
  cin >> h >> w >> k;
  int ans = mul(k, mul(C(h + w, k), fact[k]));
  if (k >= 2) {
    int cur = mul(C(h + w - 2, k - 2), fact[k - 2]);
    cur = mul(cur, (h * (ll)w) % M);
    cur = mul(cur, mul(2, s[k][2]));
    ans = add(ans, cur);
  }
  if (k >= 1) {
    int cur = mul(C(h + w - 1, k - 1), fact[k - 1]);
    cur = mul(cur, h + w);
    cur = mul(cur, os[k][1]);
    ans = add(ans, cur);
  }
  cout << ans << '\n';
}