Problem p01851 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>

#include <complex>

#include <cassert>
#include <functional>

typedef long long ll;
using namespace std;

#define debug(x) cerr << #x << " = " << (x) << endl;

#define mod 1000000007              // 1e9+7(prime number)
#define INF 1000000000              // 1e9
#define LLINF 2000000000000000000LL // 2e18
#define SIZE 3000100

ll fac[SIZE];
ll fac_in_memo[SIZE];

void factorial_init(int n) {
  fac[0] = 1;
  for (int i = 1; i <= n; i++)
    fac[i] = (i * fac[i - 1]) % mod;
}

ll factorial(int n, int M) {
  ll ret = 1;
  if (n <= 1)
    return 1;
  return fac[n];

  for (int i = 1; i <= n; i++) {
    ret = (ret * i) % M;
  }

  return ret;
}

ll power(int k, int n, int M) {
  if (n == 0)
    return 1;
  if (n == 1)
    return (ll)k;

  ll ret = power(k, n / 2, M);

  ret = (ret * ret) % M;

  if (n % 2 == 1)
    ret = (ret * k) % M;

  return ret;
}

ll fac_in(int k, int n, int M) {
  if (fac_in_memo[k])
    return fac_in_memo[k];
  return fac_in_memo[k] = power(k, n, M);
}

// nCm nPm nHm (mod M)

/*Combination*/
int C(int n, int m, int M) {
  if (n < m)
    return 0;
  if (m == 0 || n == m)
    return 1;

  ll chi = factorial(n, M);
  ll mot = (factorial(m, M) * factorial(n - m, M)) % M;

  mot = power((int)mot, M - 2, M);

  ll ret = (chi * mot) % M;

  return (int)ret;
}
/*Permutation*/
int P(int n, int m, int M) {
  if (n < m)
    return 0;
  if (m == 0)
    return 1;

  ll chi = factorial(n, M);
  ll mot = factorial(n - m, M);

  mot = power((int)mot, M - 2, M);

  ll ret = (chi * mot) % M;

  return (int)ret;
}
/*Combination with Repetitions*/
int H(int n, int m, int M) {
  if (n == 0 && m == 0)
    return 1;
  return C(n + m - 1, m, M);
}

bool solve() {
  int a, b, c, sx, sy;

  scanf("%d%d%d%d%d", &a, &b, &c, &sx, &sy);

  if (a + b + c == 0)
    return false;

  if (sx < sy) {
    swap(sx, sy);
    swap(a, b);
  }

  ll ans_sum = 0;

  for (int i = sx - sy; i <= sx; i++) {
    int p = i;
    int q = i - (sx - sy);

    if (p < a || q < b || (a == 0 && p > 0) || (b == 0 && q > 0))
      continue;

    ll ans = 1;

    ans = (ans * C(p - 1, a - 1, mod)) % mod;
    ans = (ans * C(q - 1, b - 1, mod)) % mod;
    ans = (ans * C(sx - i + (c + b + a - 1), c + b + a - 1, mod)) % mod;

    ans_sum = (ans_sum + ans) % mod;
  }

  ans_sum = (ans_sum * factorial(a + b + c, mod)) % mod;
  ans_sum = (ans_sum * power(factorial(a, mod), mod - 2, mod)) % mod;
  ans_sum = (ans_sum * power(factorial(b, mod), mod - 2, mod)) % mod;
  ans_sum = (ans_sum * power(factorial(c, mod), mod - 2, mod)) % mod;

  printf("%lld\\n", ans_sum);

  return true;
}

int main() {

  factorial_init(3000000);

  while (solve())
    ;

  return 0;
}

Error: TLE

Fixed submission:

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <complex>

#include <cassert>
#include <functional>

typedef long long ll;
using namespace std;

#define debug(x) cerr << #x << " = " << (x) << endl;

#define mod 1000000007              // 1e9+7(prime number)
#define INF 1000000000              // 1e9
#define LLINF 2000000000000000000LL // 2e18
#define SIZE 3000100

ll fac[SIZE];
ll fac_in_memo[SIZE];

void factorial_init(int n) {
  fac[0] = 1;
  for (int i = 1; i <= n; i++)
    fac[i] = (i * fac[i - 1]) % mod;
}

ll factorial(int n, int M) {
  ll ret = 1;
  if (n <= 1)
    return 1;
  return fac[n];

  for (int i = 1; i <= n; i++) {
    ret = (ret * i) % M;
  }

  return ret;
}

ll power(int k, int n, int M) {
  if (n == 0)
    return 1;
  if (n == 1)
    return (ll)k;

  ll ret = power(k, n / 2, M);

  ret = (ret * ret) % M;

  if (n % 2 == 1)
    ret = (ret * k) % M;

  return ret;
}

ll fac_in(int k, int n, int M) {
  if (fac_in_memo[k])
    return fac_in_memo[k];
  return fac_in_memo[k] = power(k, n, M);
}

// nCm nPm nHm (mod M)

/*Combination*/
int C(int n, int m, int M) {
  if (n < m)
    return 0;
  if (m == 0 || n == m)
    return 1;

  ll chi = factorial(n, M);
  ll mot = (factorial(m, M) * factorial(n - m, M)) % M;

  mot = power((int)mot, M - 2, M);

  ll ret = (chi * mot) % M;

  return (int)ret;
}
/*Permutation*/
int P(int n, int m, int M) {
  if (n < m)
    return 0;
  if (m == 0)
    return 1;

  ll chi = factorial(n, M);
  ll mot = factorial(n - m, M);

  mot = power((int)mot, M - 2, M);

  ll ret = (chi * mot) % M;

  return (int)ret;
}
/*Combination with Repetitions*/
int H(int n, int m, int M) {
  if (n == 0 && m == 0)
    return 1;
  return C(n + m - 1, m, M);
}

bool solve() {
  int a, b, c, sx, sy;

  scanf("%d%d%d%d%d", &a, &b, &c, &sx, &sy);

  if (a + b + c == 0)
    return false;

  if (sx < sy) {
    swap(sx, sy);
    swap(a, b);
  }

  ll ans_sum = 0;

  for (int i = sx - sy; i <= sx; i++) {
    int p = i;
    int q = i - (sx - sy);

    if (p < a || q < b || (a == 0 && p > 0) || (b == 0 && q > 0))
      continue;

    ll ans = 1;

    ans = (ans * C(p - 1, a - 1, mod)) % mod;
    ans = (ans * C(q - 1, b - 1, mod)) % mod;
    ans = (ans * C(sx - i + (c + b + a - 1), c + b + a - 1, mod)) % mod;

    ans = (ans * factorial(a + b + c, mod)) % mod;

    ans = (ans * power(factorial(a, mod), mod - 2, mod)) % mod;
    ans = (ans * power(factorial(b, mod), mod - 2, mod)) % mod;
    ans = (ans * power(factorial(c, mod), mod - 2, mod)) % mod;

    ans_sum = (ans_sum + ans) % mod;
  }

  printf("%lld\\n", ans_sum);

  return true;
}

int main() {

  factorial_init(3000000);

  while (solve())
    ;

  return 0;
}