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

#include <algorithm>
#include <iostream>
using namespace std;

long long fact[5000009], factinv[5000009], mod = 1000000007;

long long mul3(long long a, long long b, long long c) {
  return ((a * b) % mod) * c % mod;
}
long long mul2(long long a, long long b) { return (a * b) % mod; }
long long modpow(long long a, long long b, long long m) {
  long long p = 1, q = a;
  for (int i = 0; i < 60; i++) {
    if ((b / (1LL << i)) % 2 == 1) {
      p *= q;
      p %= m;
    }
    q *= q;
    q %= m;
  }
  return p;
}
long long Div(long long a, long long b, long long m) {
  return (a * modpow(b, m - 2, m)) % m;
}
long long ncr(long long n, long long r) {
  if (r < 0 || n < r)
    return 0;
  return mul3(fact[n], factinv[n - r], factinv[r]);
}
void init() {
  fact[0] = 1;
  for (int i = 1; i <= 5000000; i++)
    fact[i] = (fact[i - 1] * i) % mod;
  for (int i = 0; i <= 5000000; i++)
    factinv[i] = Div(1, fact[i], mod);
}
long long comb(long long a, long long b) {
  if (b == 0) {
    if (a == 0)
      return 1;
    return 0;
  }
  return ncr(a - 1, b - 1);
}

long long X, Y, A, B, C;

int main() {
  init();
  while (true) {
    cin >> A >> B >> C >> X >> Y;
    if (A + B + C + X + Y == 0)
      break;

    long long sum = 0;
    for (int i = 0; i <= min(X, Y); i++) {
      long long V1 = ncr(A + B, B) * ncr(A + B + C, C);
      V1 %= mod;
      long long V2 = comb(i + A + B + C, A + B + C);
      long long V3 = comb(X - i, A);
      long long V4 = comb(Y - i, B);
      sum += mul2(mul2(V1, V2), mul2(V3, V4));
      sum %= mod;
    }
    cout << sum << endl;
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
using namespace std;

long long fact[2000009], factinv[2000009], mod = 1000000007;

long long mul3(long long a, long long b, long long c) {
  return ((a * b) % mod) * c % mod;
}
long long mul2(long long a, long long b) { return (a * b) % mod; }
long long modpow(long long a, long long b, long long m) {
  long long p = 1, q = a;
  for (int i = 0; i < 60; i++) {
    if ((b / (1LL << i)) % 2 == 1) {
      p *= q;
      p %= m;
    }
    q *= q;
    q %= m;
  }
  return p;
}
long long Div(long long a, long long b, long long m) {
  return (a * modpow(b, m - 2, m)) % m;
}
long long ncr(long long n, long long r) {
  if (r < 0 || n < r)
    return 0;
  return mul3(fact[n], factinv[n - r], factinv[r]);
}
void init() {
  fact[0] = 1;
  for (int i = 1; i <= 2000000; i++)
    fact[i] = (fact[i - 1] * i) % mod;
  for (int i = 0; i <= 2000000; i++)
    factinv[i] = Div(1, fact[i], mod);
}
long long comb(long long a, long long b) {
  if (b == 0) {
    if (a == 0)
      return 1;
    return 0;
  }
  return ncr(a - 1, b - 1);
}

long long X, Y, A, B, C;

int main() {
  init();
  while (true) {
    cin >> A >> B >> C >> X >> Y;
    if (A + B + C + X + Y == 0)
      break;

    long long sum = 0;
    for (int i = 0; i <= min(X, Y); i++) {
      long long V1 = ncr(A + B, B) * ncr(A + B + C, C);
      V1 %= mod;
      long long V2 = comb(i + A + B + C, A + B + C);
      long long V3 = comb(X - i, A);
      long long V4 = comb(Y - i, B);
      sum += mul2(mul2(V1, V2), mul2(V3, V4));
      sum %= mod;
    }
    cout << sum << endl;
  }
  return 0;
}