Problem p02782 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <iostream>
#include <iterator>
#include <map>
#include <queue>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vi2;
typedef vector<vi2> vi3;
typedef pair<int, int> pii;
typedef vector<pii> vii;
typedef vector<ll> vll;
typedef vector<vll> vll2;
typedef vector<vll2> vll3;
typedef vector<bool> vb;

#define el '\n'
#define rep(i, a, b) for (int i = a; i < b; i++)
#define repi(i, a, b) for (int i = a; i >= b; i--)
#define umap unordered_map
#define uset unordered_set
#define vec vector
#define loop(a) for (auto &x : a)
#define all(a) a.begin(), a.end()
#define mp make_pair

const ll modulo = 1e9 + 7;

void add_self(ll &a, ll b) {
  a += b;
  if (a >= modulo) {
    a -= modulo;
  }
}

ll sub(ll a, ll b) {
  a -= b;
  if (a < 0) {
    a += modulo;
  }
  return a;
}

ll mul(ll a, ll b) { return a * b % modulo; }

vll fac, fnv;

ll c(int total, int chosen) {
  if (total < chosen) {
    return 0;
  }
  if (chosen == 0 || total == chosen) {
    return 1;
  }
  return mul(mul(fac[total], fnv[chosen]), fnv[total - chosen]);
}

ll extgcd(ll a, ll b, ll &x, ll &y) {
  if (a == 0) {
    x = 0;
    y = 1;
    return b;
  }
  ll x1, y1;
  ll d = extgcd(b % a, a, x1, y1);
  x = y1 - (b / a) * x1;
  y = x1;
  return d;
}

ll invmod(ll a, ll m) {
  ll x, y;
  ll g = extgcd(a, m, x, y);
  if (g != 1) {
    return -1;
  } else {
    x = (x % m + m) % m;
    return x;
  }
}

void init() {
  fac = vll(1e6);
  fnv = vll(1e6);
  fac[0] = fac[1] = 1;
  fnv[0] = fnv[1] = 1;
  rep(i, 2, fac.size()) {
    fac[i] = mul(fac[i - 1], i);
    ll work = invmod(i, modulo);
    fnv[i] = mul(fnv[i - 1], work);
  }
}

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);

  int r1, c1, r2, c2;
  cin >> r1 >> c1 >> r2 >> c2;

  init();

  ll ans = 0;
  rep(i, r1, r2 + 1) {
    add_self(ans, sub(c(i + c2 + 1, i + 1), c(i + c1, i + 1)));
  }
  cout << ans;
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <iostream>
#include <iterator>
#include <map>
#include <queue>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vi2;
typedef vector<vi2> vi3;
typedef pair<int, int> pii;
typedef vector<pii> vii;
typedef vector<ll> vll;
typedef vector<vll> vll2;
typedef vector<vll2> vll3;
typedef vector<bool> vb;

#define el '\n'
#define rep(i, a, b) for (int i = a; i < b; i++)
#define repi(i, a, b) for (int i = a; i >= b; i--)
#define umap unordered_map
#define uset unordered_set
#define vec vector
#define loop(a) for (auto &x : a)
#define all(a) a.begin(), a.end()
#define mp make_pair

const ll modulo = 1e9 + 7;

void add_self(ll &a, ll b) {
  a += b;
  if (a >= modulo) {
    a -= modulo;
  }
}

ll sub(ll a, ll b) {
  a -= b;
  if (a < 0) {
    a += modulo;
  }
  return a;
}

ll mul(ll a, ll b) { return a * b % modulo; }

vll fac, fnv;

ll c(int total, int chosen) {
  if (total < chosen) {
    return 0;
  }
  if (chosen == 0 || total == chosen) {
    return 1;
  }
  return mul(mul(fac[total], fnv[chosen]), fnv[total - chosen]);
}

ll extgcd(ll a, ll b, ll &x, ll &y) {
  if (a == 0) {
    x = 0;
    y = 1;
    return b;
  }
  ll x1, y1;
  ll d = extgcd(b % a, a, x1, y1);
  x = y1 - (b / a) * x1;
  y = x1;
  return d;
}

ll invmod(ll a, ll m) {
  ll x, y;
  ll g = extgcd(a, m, x, y);
  if (g != 1) {
    return -1;
  } else {
    x = (x % m + m) % m;
    return x;
  }
}

void init() {
  fac = vll(2e6 + 100);
  fnv = vll(2e6 + 100);
  fac[0] = fac[1] = 1;
  fnv[0] = fnv[1] = 1;
  rep(i, 2, fac.size()) {
    fac[i] = mul(fac[i - 1], i);
    ll work = invmod(i, modulo);
    fnv[i] = mul(fnv[i - 1], work);
  }
}

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);

  int r1, c1, r2, c2;
  cin >> r1 >> c1 >> r2 >> c2;

  init();

  ll ans = 0;
  rep(i, r1, r2 + 1) {
    add_self(ans, sub(c(i + c2 + 1, i + 1), c(i + c1, i + 1)));
  }
  cout << ans;
}