Problem p03152 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef vector<int> VI;
typedef vector<VI> VVI;
#define MP make_pair
#define PB push_back
#define inf 1000000007
#define mod 1000000007
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)

template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val) {
  std::fill((T *)array, (T *)(array + N), val);
}

#define MAX_N 100005
#define MOD 1000000007

ll inv[MAX_N], fac[MAX_N], finv[MAX_N];

void make() {
  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for (int i = 2; i < MAX_N; i++) {
    inv[i] = MOD - (long long)inv[MOD % i] * (MOD / i) % MOD;
    fac[i] = (long long)fac[i - 1] * i % MOD;
    finv[i] = (long long)finv[i - 1] * inv[i] % MOD;
  }
}

ll com(int a, int b) {
  // cerr << a << " " << b << endl;
  if (a < b) {
    return 0;
  }
  return fac[a] * (finv[a - b] % MOD) % MOD;
}

int main() {
  int n, m;
  make();
  cin >> n >> m;
  vector<int> a(n), b(m);
  rep(i, n) cin >> a[i];
  rep(i, m) cin >> b[i];
  sort(a.begin(), a.end());
  sort(b.begin(), b.end());
  int x = 0;
  int y = 0;
  int c = 0;
  ll ans = 1;
  if (a[n - 1] != b[m - 1]) {
    cout << 0 << endl;
    return 0;
  }
  rep(i, n - 1) {
    if (a[i] == a[i + 1]) {
      cout << 0 << endl;
      return 0;
    }
  }
  rep(i, m - 1) {
    if (b[i] == b[i + 1]) {
      cout << 0 << endl;
      return 0;
    }
  }
  while (1) {
    // cerr << x << " " << y << " " << ans << endl;
    if (x == n && y == m)
      break;
    if (x == n) {
      int p = b[y];
      ll tmp = com(p - c - 1, n - x - 1) * (ll)(n - x) % mod;
      ans *= tmp;
      ans %= mod;

      c += n - x;
      y++;
    } else if (y == m) {
      int p = a[x];
      ll tmp = com(p - c - 1, m - y - 1) * (ll)(m - y) % mod;
      ans *= tmp;
      ans %= mod;
      x++;
      c += m - y;
    } else {
      if (a[x] == b[y]) {
        int p = a[x];
        ll tmp = com(p - c - 1, m - 1 - y + n - 1 - x);
        ans *= tmp;
        ans %= mod;
        c += m - 1 - y + n - 1 - x + 1;
        x++;
        y++;
      } else if (a[x] > b[y]) {
        int p = b[y];
        ll tmp = com(p - c - 1, n - x - 1) * (ll)(n - x) % mod;
        ans *= tmp;
        ans %= mod;

        c += n - x;
        y++;
      } else {
        int p = a[x];
        ll tmp = com(p - c - 1, m - y - 1) * (ll)(m - y) % mod;
        ans *= tmp;
        ans %= mod;
        x++;
        c += m - y;
      }
    }
    if (ans == 0)
      break;
  }
  cout << ans << endl;
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef vector<int> VI;
typedef vector<VI> VVI;
#define MP make_pair
#define PB push_back
#define inf 1000000007
#define mod 1000000007
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)

template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val) {
  std::fill((T *)array, (T *)(array + N), val);
}

#define MAX_N 2000005
#define MOD 1000000007

ll inv[MAX_N], fac[MAX_N], finv[MAX_N];

void make() {
  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for (int i = 2; i < MAX_N; i++) {
    inv[i] = MOD - (long long)inv[MOD % i] * (MOD / i) % MOD;
    fac[i] = (long long)fac[i - 1] * i % MOD;
    finv[i] = (long long)finv[i - 1] * inv[i] % MOD;
  }
}

ll com(int a, int b) {
  // cerr << a << " " << b << endl;
  if (a < b) {
    return 0;
  }
  return fac[a] * (finv[a - b] % MOD) % MOD;
}

int main() {
  int n, m;
  make();
  cin >> n >> m;
  vector<int> a(n), b(m);
  rep(i, n) cin >> a[i];
  rep(i, m) cin >> b[i];
  sort(a.begin(), a.end());
  sort(b.begin(), b.end());
  int x = 0;
  int y = 0;
  int c = 0;
  ll ans = 1;
  if (a[n - 1] != b[m - 1]) {
    cout << 0 << endl;
    return 0;
  }
  rep(i, n - 1) {
    if (a[i] == a[i + 1]) {
      cout << 0 << endl;
      return 0;
    }
  }
  rep(i, m - 1) {
    if (b[i] == b[i + 1]) {
      cout << 0 << endl;
      return 0;
    }
  }
  while (1) {
    // cerr << x << " " << y << " " << ans << endl;
    if (x == n && y == m)
      break;
    if (x == n) {
      int p = b[y];
      ll tmp = com(p - c - 1, n - x - 1) * (ll)(n - x) % mod;
      ans *= tmp;
      ans %= mod;

      c += n - x;
      y++;
    } else if (y == m) {
      int p = a[x];
      ll tmp = com(p - c - 1, m - y - 1) * (ll)(m - y) % mod;
      ans *= tmp;
      ans %= mod;
      x++;
      c += m - y;
    } else {
      if (a[x] == b[y]) {
        int p = a[x];
        ll tmp = com(p - c - 1, m - 1 - y + n - 1 - x);
        ans *= tmp;
        ans %= mod;
        c += m - 1 - y + n - 1 - x + 1;
        x++;
        y++;
      } else if (a[x] > b[y]) {
        int p = b[y];
        ll tmp = com(p - c - 1, n - x - 1) * (ll)(n - x) % mod;
        ans *= tmp;
        ans %= mod;

        c += n - x;
        y++;
      } else {
        int p = a[x];
        ll tmp = com(p - c - 1, m - y - 1) * (ll)(m - y) % mod;
        ans *= tmp;
        ans %= mod;
        x++;
        c += m - y;
      }
    }
    if (ans == 0)
      break;
  }
  cout << ans << endl;
  return 0;
}