Problem p02768 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>

typedef long long ll;
typedef unsigned long long ull;
using namespace std;

#define FALSE printf("false\n");
#define TRUE printf("true\n");
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < ((int)(n)); ++i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());
#define test(a)                                                                \
  cout << "line:" << __LINE__ << "[" << (#a) << ": " << (a) << "]" << endl

const int INF = 1e9 + 7;
const ll INFL = 9 * 1e18;

// const int dx[4] = { 1, 0, -1, 0 };
// const int dy[4] = { 0, 1, 0, -1 };

// const int dx[8] = {1, 1, 0,-1,-1,-1, 0, 1};
// const int dy[8] = {0, 1, 1, 1, 0,-1,-1,-1};

#define SUM(vec) accumulate(all(vec), 0LL) // 配列の中身を全部足す
template <typename T> void print(T &&x) { cout << x << endl; } // 改行付き出力
ll inline digit(ll num) {
  int tmp = 0;
  while (num) {
    tmp++;
    num /= 10;
  }
  return tmp;
} // 桁数
template <typename T> inline T digitSum(T num) {
  T sum = 0;
  while (num) {
    sum += num % 10;
    num /= 10;
  }
  return sum;
} // 各桁の和
template <typename T> inline T gcd(T a, T b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
} // 最大公約数
template <typename T> inline T lcm(T a, T b) {
  T g = gcd(a, b);
  return a / g * b;
} // 最小公倍数
template <typename T> inline T power(T a, T b) {
  T tmp = 1;
  rep(i, b) { tmp *= a; }
  return tmp;
} // 累乗
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
int ctoi(char c) { return c - '0'; }

const ll COM_MAX = (ll)(1e6 + 100); // combinationの最大値
vector<ll> fac(COM_MAX), finv(COM_MAX), inv(COM_MAX);

void comb_init() {
  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for (int i = 2; i < COM_MAX; ++i) {
    fac[i] = fac[i - 1] * i % INF;
    inv[i] = INF - inv[INF % i] * (INF / i) % INF;
    finv[i] = finv[i - 1] * inv[i] % INF;
  }
}

ll comb(ll n, ll k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac[n] * (finv[k] * finv[n - k] % INF) % INF;
}

template <long long MOD> struct mod_int {
  using ll = long long;
  ll val;
  constexpr mod_int() : val(0) {}
  constexpr mod_int(ll x) noexcept
      : val(x >= 0 ? x % MOD : (MOD - (-x) % MOD) % MOD) {}
  constexpr ll value() const noexcept { return val; }
  constexpr mod_int operator+(mod_int const &rhs) {
    return mod_int(*this) += rhs;
  }
  constexpr mod_int operator-(mod_int const &rhs) {
    return mod_int(*this) -= rhs;
  }
  constexpr mod_int operator*(mod_int const &rhs) {
    return mod_int(*this) *= rhs;
  }
  constexpr mod_int operator/(mod_int const &rhs) {
    return mod_int(*this) /= rhs;
  }
  constexpr mod_int &operator+=(mod_int const &rhs) noexcept {
    val += rhs.val;
    if (val >= MOD)
      val -= MOD;
    return *this;
  }
  constexpr mod_int &operator-=(mod_int const &rhs) noexcept {
    if (val < rhs.val)
      val += MOD;
    val -= rhs.val;
    return *this;
  }
  constexpr mod_int &operator*=(mod_int const &rhs) noexcept {
    (val *= rhs.val) %= MOD;
    return *this;
  }
  constexpr mod_int &operator/=(mod_int rhs) noexcept {
    *this *= rhs.inverse();
    return *this;
  }
  constexpr bool operator==(mod_int const &rhs) const { return val == rhs.val; }
  constexpr bool operator!=(mod_int const &rhs) const {
    return !(val == rhs.val);
  }
  constexpr bool operator<(mod_int const &rhs) const { return val < rhs.val; }
  constexpr bool operator>(mod_int const &rhs) const { return val > rhs.val; }
  constexpr bool operator<=(mod_int const &rhs) const {
    return !(val > rhs.val);
  }
  constexpr bool operator>=(mod_int const &rhs) const {
    return !(val < rhs.val);
  }
  constexpr friend std::ostream &operator<<(std::ostream &os,
                                            mod_int const &mi) {
    return os << mi.val;
  }
  constexpr friend std::istream &operator>>(std::istream &is, mod_int &mi) {
    ll t;
    is >> t;
    mi = mod_int<MOD>(t);
    return is;
  }
  constexpr mod_int inverse() {
    ll a = val, b = MOD, u = 1, v = 0, t = 1;
    while (b > 0) {
      t = a / b;
      std::swap(a -= t * b, b);
      std::swap(u -= t * v, v);
    }
    return mod_int(u);
  }
  constexpr mod_int mpow(ll n) const {
    mod_int res(1), e(*this);
    while (n) {
      if (n & 1)
        res *= e;
      e *= e;
      n >>= 1;
    }
    return res;
  }
};
using mint = mod_int<1000000007>;

mint mpow(ll x, ll n) {
  mint res(1), e(x);
  while (n) {
    if (n & 1)
      res *= e;
    e *= e;
    n >>= 1;
  }
  return res;
}

// TODO: write
int main() {
  int n;
  cin >> n;
  int a, b;
  cin >> a >> b;
  comb_init();
  if (n == 2) {
    print(0);
    return 0;
  }
  mint ans = mpow(2, n) - 1;
  ans -= comb(n, a);
  ans -= comb(n, b);
  print(ans);
  return 0;
}


Fixed submission:
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>

typedef long long ll;
typedef unsigned long long ull;
using namespace std;

#define FALSE printf("false\n");
#define TRUE printf("true\n");
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < ((int)(n)); ++i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());
#define test(a)                                                                \
  cout << "line:" << __LINE__ << "[" << (#a) << ": " << (a) << "]" << endl

const int INF = 1e9 + 7;
const ll INFL = 9 * 1e18;

// const int dx[4] = { 1, 0, -1, 0 };
// const int dy[4] = { 0, 1, 0, -1 };

// const int dx[8] = {1, 1, 0,-1,-1,-1, 0, 1};
// const int dy[8] = {0, 1, 1, 1, 0,-1,-1,-1};

#define SUM(vec) accumulate(all(vec), 0LL) // 配列の中身を全部足す
template <typename T> void print(T &&x) { cout << x << endl; } // 改行付き出力
ll inline digit(ll num) {
  int tmp = 0;
  while (num) {
    tmp++;
    num /= 10;
  }
  return tmp;
} // 桁数
template <typename T> inline T digitSum(T num) {
  T sum = 0;
  while (num) {
    sum += num % 10;
    num /= 10;
  }
  return sum;
} // 各桁の和
template <typename T> inline T gcd(T a, T b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
} // 最大公約数
template <typename T> inline T lcm(T a, T b) {
  T g = gcd(a, b);
  return a / g * b;
} // 最小公倍数
template <typename T> inline T power(T a, T b) {
  T tmp = 1;
  rep(i, b) { tmp *= a; }
  return tmp;
} // 累乗
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
int ctoi(char c) { return c - '0'; }

const ll COM_MAX = (ll)(1e6 + 100); // combinationの最大値
vector<ll> fac(COM_MAX), finv(COM_MAX), inv(COM_MAX);

void comb_init() {
  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for (int i = 2; i < COM_MAX; ++i) {
    fac[i] = fac[i - 1] * i % INF;
    inv[i] = INF - inv[INF % i] * (INF / i) % INF;
    finv[i] = finv[i - 1] * inv[i] % INF;
  }
}

ll comb(ll n, ll k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac[n] * (finv[k] * finv[n - k] % INF) % INF;
}

template <long long MOD> struct mod_int {
  using ll = long long;
  ll val;
  constexpr mod_int() : val(0) {}
  constexpr mod_int(ll x) noexcept
      : val(x >= 0 ? x % MOD : (MOD - (-x) % MOD) % MOD) {}
  constexpr ll value() const noexcept { return val; }
  constexpr mod_int operator+(mod_int const &rhs) {
    return mod_int(*this) += rhs;
  }
  constexpr mod_int operator-(mod_int const &rhs) {
    return mod_int(*this) -= rhs;
  }
  constexpr mod_int operator*(mod_int const &rhs) {
    return mod_int(*this) *= rhs;
  }
  constexpr mod_int operator/(mod_int const &rhs) {
    return mod_int(*this) /= rhs;
  }
  constexpr mod_int &operator+=(mod_int const &rhs) noexcept {
    val += rhs.val;
    if (val >= MOD)
      val -= MOD;
    return *this;
  }
  constexpr mod_int &operator-=(mod_int const &rhs) noexcept {
    if (val < rhs.val)
      val += MOD;
    val -= rhs.val;
    return *this;
  }
  constexpr mod_int &operator*=(mod_int const &rhs) noexcept {
    (val *= rhs.val) %= MOD;
    return *this;
  }
  constexpr mod_int &operator/=(mod_int rhs) noexcept {
    *this *= rhs.inverse();
    return *this;
  }
  constexpr bool operator==(mod_int const &rhs) const { return val == rhs.val; }
  constexpr bool operator!=(mod_int const &rhs) const {
    return !(val == rhs.val);
  }
  constexpr bool operator<(mod_int const &rhs) const { return val < rhs.val; }
  constexpr bool operator>(mod_int const &rhs) const { return val > rhs.val; }
  constexpr bool operator<=(mod_int const &rhs) const {
    return !(val > rhs.val);
  }
  constexpr bool operator>=(mod_int const &rhs) const {
    return !(val < rhs.val);
  }
  constexpr friend std::ostream &operator<<(std::ostream &os,
                                            mod_int const &mi) {
    return os << mi.val;
  }
  constexpr friend std::istream &operator>>(std::istream &is, mod_int &mi) {
    ll t;
    is >> t;
    mi = mod_int<MOD>(t);
    return is;
  }
  constexpr mod_int inverse() {
    ll a = val, b = MOD, u = 1, v = 0, t = 1;
    while (b > 0) {
      t = a / b;
      std::swap(a -= t * b, b);
      std::swap(u -= t * v, v);
    }
    return mod_int(u);
  }
  constexpr mod_int mpow(ll n) const {
    mod_int res(1), e(*this);
    while (n) {
      if (n & 1)
        res *= e;
      e *= e;
      n >>= 1;
    }
    return res;
  }
};
using mint = mod_int<1000000007>;

mint mpow(ll x, ll n) {
  mint res(1), e(x);
  while (n) {
    if (n & 1)
      res *= e;
    e *= e;
    n >>= 1;
  }
  return res;
}

// TODO: write
int main() {
  int n;
  cin >> n;
  int a, b;
  cin >> a >> b;
  comb_init();
  if (n == 2) {
    print(0);
    return 0;
  }
  mint ans = mpow(2, n) - 1;
  mint aKai = 1;
  mint bKai = 1;
  rep(i, a + 1) if (i) aKai *= i;
  rep(i, b + 1) if (i) bKai *= i;

  mint aTmp = 1;
  rep(i, a) aTmp *= (n - i);
  ans -= aTmp / aKai;
  mint bTmp = 1;
  rep(i, b) bTmp *= (n - i);
  ans -= bTmp / bKai;
  print(ans);
  return 0;
}