Problem p03154 (C++)

Buggy submission (status: Runtime Error):
// #define _GLIBCXX_DEBUG // for STL debug (optional)
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define debug(...) fprintf(stderr, __VA_ARGS__)
#define int long long int

template <typename T> void chmax(T &a, T b) { a = max(a, b); }
template <typename T> void chmin(T &a, T b) { a = min(a, b); }
template <typename T> void chadd(T &a, T b) { a = a + b; }

typedef pair<int, int> pii;
typedef long long ll;

int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const ll INF = 1001001001001001LL;
const ll MOD = 1000000007LL;

const int S = 10000010;
int fact[S + 10], finv[S + 10];

int mod_pow(int n, int k) {
  int res = 1;
  for (; k > 0; k >>= 1) {
    if (k & 1)
      (res *= n) %= MOD;
    (n *= n) %= MOD;
  }
  return res;
}

void init() {
  fact[0] = 1;
  for (int i = 1; i <= S; i++)
    fact[i] = (fact[i - 1] * i) % MOD;
  finv[S] = mod_pow(fact[S], MOD - 2);
  for (int i = S - 1; i >= 0; i--)
    finv[i] = (finv[i + 1] * (i + 1)) % MOD;
}

int perm(int n, int r) {
  if (r < 0 or n < r)
    return 0;
  return fact[n] * finv[n - r] % MOD;
}

signed main() {
  init();
  int H, W, K;
  cin >> H >> W >> K;
  int N = H + W;

  // 2 個切る必要がある、1 個切る必要がある、1 個も切る必要ない
  int c1 = 0, c2 = 0, c3 = perm(N, K) * K % MOD;
  for (int i = 1; i <= K; i++) {
    // i 番目で初めて切れた
    if (i >= 2) {
      int temp = 2 * (i - 1);
      (temp *= perm(N - 2, K - 2)) %= MOD;
      (temp *= K - i + 1) %= MOD;
      (c1 += temp) %= MOD;
    }
    if (i >= 1) {
      int temp = perm(N - 1, K - 1);
      (temp *= K - i + 1) %= MOD;
      (c2 += temp) %= MOD;
    }
  }
  // fprintf(stderr, "c1 = %lld, c2 = %lld, c3 = %lld\n", c1, c2, c3);

  int h1 = H * W % MOD;
  int h2 = (H + W) % MOD;
  int h3 = 1;

  int ans = 0;
  (ans += h1 * c1) %= MOD;
  (ans += h2 * c2) %= MOD;
  (ans += h3 * c3) %= MOD;
  cout << ans << endl;
  return 0;
}


Fixed submission:
// #define _GLIBCXX_DEBUG // for STL debug (optional)
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define debug(...) fprintf(stderr, __VA_ARGS__)
#define int long long int

template <typename T> void chmax(T &a, T b) { a = max(a, b); }
template <typename T> void chmin(T &a, T b) { a = min(a, b); }
template <typename T> void chadd(T &a, T b) { a = a + b; }

typedef pair<int, int> pii;
typedef long long ll;

int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const ll INF = 1001001001001001LL;
const ll MOD = 1000000007LL;

const int S = 20000010;
int fact[S + 10], finv[S + 10];

int mod_pow(int n, int k) {
  int res = 1;
  for (; k > 0; k >>= 1) {
    if (k & 1)
      (res *= n) %= MOD;
    (n *= n) %= MOD;
  }
  return res;
}

void init() {
  fact[0] = 1;
  for (int i = 1; i <= S; i++)
    fact[i] = (fact[i - 1] * i) % MOD;
  finv[S] = mod_pow(fact[S], MOD - 2);
  for (int i = S - 1; i >= 0; i--)
    finv[i] = (finv[i + 1] * (i + 1)) % MOD;
}

int perm(int n, int r) {
  if (r < 0 or n < r)
    return 0;
  return fact[n] * finv[n - r] % MOD;
}

signed main() {
  init();
  int H, W, K;
  cin >> H >> W >> K;
  int N = H + W;

  // 2 個切る必要がある、1 個切る必要がある、1 個も切る必要ない
  int c1 = 0, c2 = 0, c3 = perm(N, K) * K % MOD;
  for (int i = 1; i <= K; i++) {
    // i 番目で初めて切れた
    if (i >= 2) {
      int temp = 2 * (i - 1);
      (temp *= perm(N - 2, K - 2)) %= MOD;
      (temp *= K - i + 1) %= MOD;
      (c1 += temp) %= MOD;
    }
    if (i >= 1) {
      int temp = perm(N - 1, K - 1);
      (temp *= K - i + 1) %= MOD;
      (c2 += temp) %= MOD;
    }
  }
  // fprintf(stderr, "c1 = %lld, c2 = %lld, c3 = %lld\n", c1, c2, c3);

  int h1 = H * W % MOD;
  int h2 = (H + W) % MOD;
  int h3 = 1;

  int ans = 0;
  (ans += h1 * c1) %= MOD;
  (ans += h2 * c2) %= MOD;
  (ans += h3 * c3) %= MOD;
  cout << ans << endl;
  return 0;
}