Problem p02768 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
// #pragma GCC target ("avx2")
// #pragma GCC optimization ("O3")
// #pragma GCC optimization ("unroll-loops")

#define clz __builtin_clzll
#define popcount __builtin_popcountll
#define FORS(i, s, n) for (i64 i = (s); i < (n); ++i)
#define RFORS(i, s, n) for (i64 i = (n)-1; i >= (s); --i)
#define FOR(i, n) FORS(i, 0, n)
#define RFOR(i, n) RFORS(i, 0, n)
#define FI(n) FOR(i, n)
#define RFI(n) RFOR(i, n)
#define ALL(x) (x).begin(), (x).end()
#define RALL(x) (x).rbegin(), (x).rend()
#define SZ(c) i64((c).size())
#define FOR_SETTED_BIT(bit, mask)                                              \
  for (int bit = 0; (mask) >> bit; ++bit)                                      \
    if (1 & (mask >> bit))
#define FOR_NONZERO_SUBMASK(submask, mask)                                     \
  for (int submask = (mask); submask; submask = (submask - 1) & (mask))
#define PI (3.141592653589793L)
#define MODULO ((i64)1e9 + 7LL)

using namespace std;

typedef int_fast8_t i8;
typedef int_fast16_t i16;
typedef int_fast32_t i32;
typedef int_fast64_t i64;
typedef uint_fast8_t u8;
typedef uint_fast16_t u16;
typedef uint_fast32_t u32;
typedef uint_fast64_t u64;
typedef pair<i64, i64> pi64;
typedef vector<i8> vb;
typedef vector<i32> vi32;
typedef vector<i64> vi64;
typedef vector<vi64> vvi64;
typedef vector<list<int>> AdjacencyLists;
typedef vector<list<pair<int, i64>>> WeightedAdjacencyLists;
typedef vvi64 AdjacencyMatrix;

template <class T> inline T sqr(const T &x) { return x * x; }
inline i64 sqr(int x) { return sqr<i64>(x); }
template <class T> T binpow(const T &a, i64 n) {
  return n == T(0) ? T(1) : sqr(binpow(a, n / 2)) * (n % 2 ? a : T(1));
}
i64 binpow(i64 a, i64 n, i64 modulo) {
  return n == 0 ? 1
                : sqr(binpow(a, n / 2, modulo)) % modulo * (n % 2 ? a : 1) %
                      modulo;
}
constexpr inline i64 phi(i64 n) {
  i64 result = n;
  for (i64 i = 2; i * i <= n; ++i)
    if (n % i == 0) {
      while (n % i == 0)
        n /= i;
      result -= result / i;
    }
  if (n > 1)
    result -= result / n;
  return result;
}

inline vi64 inverseAll(i64 m) {
  vi64 r(m);
  r[1] = 1;

  for (int i = 2; i < m; ++i)
    r[i] = (m - (m / i) * r[m % i] % m) % m;
  return r;
}
i64 gcd(i64 a, i64 b, i64 &x, i64 &y) {
  if (a == 0) {
    x = 0;
    y = 1;
    return b;
  }
  i64 x1, y1;
  i64 d = gcd(b % a, a, x1, y1);
  x = y1 - (b / a) * x1;
  y = x1;
  return d;
}
inline i64 gcd(i64 a, i64 b) { return gcd(a, b, a, b); }
inline i64 lcm(i64 a, i64 b) { return a / gcd(a, b) * b; }

template <class T, const T modulo, class TT = i64> class IntModulo {
  constexpr static const T order = phi(modulo);

  T value;

public:
  explicit IntModulo(const TT &value = 0)
      : value(T(((abs(value) + modulo - TT(1)) / modulo * modulo + value) %
                modulo)) {}

  inline IntModulo &operator+=(const IntModulo &i) {
    value = T((TT(value) + TT(i.value)) % modulo);
    return *this;
  }
  inline IntModulo &operator-=(const IntModulo &i) { return *this += -i; }
  inline IntModulo &operator*=(const IntModulo &i) {
    value = T((TT(value) * TT(i.value)) % modulo);
    return *this;
  }
  inline IntModulo &operator/=(const IntModulo &i) {
    return *this *= i.inverse();
  };

  inline IntModulo inverse() const { return binpow(*this, order - 1); };

  inline operator T() const { return value; }

  friend inline IntModulo operator-(const IntModulo &i) {
    return IntModulo<T, modulo, TT>(modulo - i.value);
  }

  friend inline bool operator==(const IntModulo &a, const IntModulo &b) {
    return a.value == b.value;
  }
};

template <class T, const T modulo, class TT = i64>
inline IntModulo<T, modulo, TT> operator+(const IntModulo<T, modulo, TT> &a,
                                          const IntModulo<T, modulo, TT> &b) {
  return IntModulo<T, modulo, TT>(a) += b;
}

template <class T, const T modulo, class TT = i64>
inline IntModulo<T, modulo, TT> operator-(const IntModulo<T, modulo, TT> &a,
                                          const IntModulo<T, modulo, TT> &b) {
  return IntModulo<T, modulo, TT>(a) -= b;
}

template <class T, const T modulo, class TT = i64>
inline IntModulo<T, modulo, TT> operator*(const IntModulo<T, modulo, TT> &a,
                                          const IntModulo<T, modulo, TT> &b) {
  return IntModulo<T, modulo, TT>(a) *= b;
}

template <class T, const T modulo, class TT = i64>
inline IntModulo<T, modulo, TT> operator/(const IntModulo<T, modulo, TT> &a,
                                          const IntModulo<T, modulo, TT> &b) {
  return IntModulo<T, modulo, TT>(a) /= b;
}

template <class T, const T modulo, class TT = i64>
inline bool operator!=(const IntModulo<T, modulo, TT> &a,
                       const IntModulo<T, modulo, TT> &b) {
  return !(a == b);
}

mt19937_64 rng(
#ifdef DEBUG
    0LL
#else
    chrono::steady_clock::now().time_since_epoch().count()
#endif
);
inline i64 random(i64 low, i64 high) {
  return uniform_int_distribution<i64>(low, high)(rng);
}
inline i64 random(i64 high = numeric_limits<i64>::max()) {
  return random(0, high);
}
#define rand random

struct Dinic {
  struct Edge {
    int u, v;
    i64 cap, flow;
    Edge() {}
    Edge(int u, int v, i64 cap) : u(u), v(v), cap(cap), flow(0) {}
  };

  int N;
  vector<Edge> E;
  vector<vector<int>> g;
  vector<int> d, pt;

  Dinic(int N) : N(N), E(0), g(N), d(N), pt(N) {}

  void AddEdge(int u, int v, i64 cap) {
    if (u != v) {
      E.emplace_back(Edge(u, v, cap));
      g[u].emplace_back(E.size() - 1);
      E.emplace_back(Edge(v, u, 0));
      g[v].emplace_back(E.size() - 1);
    }
  }

  bool BFS(int S, int T) {
    queue<int> q({S});
    fill(d.begin(), d.end(), N + 1);
    d[S] = 0;
    while (!q.empty()) {
      int u = q.front();
      q.pop();
      if (u == T)
        break;
      for (int k : g[u]) {
        Edge &e = E[k];
        if (e.flow < e.cap && d[e.v] > d[e.u] + 1) {
          d[e.v] = d[e.u] + 1;
          q.emplace(e.v);
        }
      }
    }
    return d[T] != N + 1;
  }

  i64 DFS(int u, int T, i64 flow = -1) {
    if (u == T || flow == 0)
      return flow;
    for (int &i = pt[u]; i < g[u].size(); ++i) {
      Edge &e = E[g[u][i]];
      Edge &oe = E[g[u][i] ^ 1];
      if (d[e.v] == d[e.u] + 1) {
        i64 amt = e.cap - e.flow;
        if (flow != -1 && amt > flow)
          amt = flow;
        if (i64 pushed = DFS(e.v, T, amt)) {
          e.flow += pushed;
          oe.flow -= pushed;
          return pushed;
        }
      }
    }
    return 0;
  }

  i64 MaxFlow(int S, int T) {
    i64 total = 0;
    while (BFS(S, T)) {
      fill(pt.begin(), pt.end(), 0);
      while (i64 flow = DFS(S, T))
        total += flow;
    }
    return total;
  }
};

vi64 Dijkstra(const WeightedAdjacencyLists &g, int s) {
  vi64 d(SZ(g), numeric_limits<i64>::max() / 2LL);
  priority_queue<pair<i64, int>> q;

  d[s] = 0;
  q.emplace(-0, s);

  while (!q.empty()) {
    if (q.top().first > d[q.top().second]) {
      q.pop();

      continue;
    }
    int v = q.top().second;

    q.pop();

    for (const auto &cw : g[v]) {
      if (d[v] + cw.second < d[cw.first]) {
        d[cw.first] = d[v] + cw.second;
        q.emplace(-d[cw.first], cw.first);
      }
    }
  }

  return d;
}

struct UnionFind {
  vi64 parent;
  vi64 rank;
  UnionFind(i64 n) : parent(n), rank(n) {
    for (i64 i = 0; i < n; ++i) {
      parent[i] = i;
      rank[i] = 0;
    }
  }
  i64 find_set(i64 v) {
    if (v == parent[v])
      return v;
    return parent[v] = find_set(parent[v]);
  }
  void union_sets(i64 a, i64 b) {
    a = find_set(a);
    b = find_set(b);
    if (a != b) {
      if (rank[a] < rank[b])
        swap(a, b);
      parent[b] = a;
      if (rank[a] == rank[b])
        ++rank[a];
    }
  }
};

// https://codeforces.com/blog/entry/18051
template <class T> const T assign(const T &a, const T &b) { return b; }

template <class T> const T &my_min(const T &a, const T &b) {
  return a < b ? a : b;
}

template <class T> struct SegmentTree {
  typedef function<T(T, T)> Function;

  const i64 n;
  vector<T> t;
  const function<T(const T &, const T &)> operation;
  const T &operation_default_value;
  const function<T(const T &, const T &)> modification;
  const T &modification_default_value;

  SegmentTree() {}

  SegmentTree(const i64 n, Function operation,
              const T &operation_default_value = T(),
              Function modification = assign<T>,
              const T &modification_default_value = T())
      : n(n), t(n << 1, operation_default_value), operation(operation),
        operation_default_value(operation_default_value),
        modification(modification),
        modification_default_value(modification_default_value) {
    build();
  }

  template <class Iterator>
  SegmentTree(const Iterator &begin, const Iterator &end, Function operation,
              const T &operation_default_value = T(),
              Function modification = assign<T>,
              const T &modification_default_value = T())
      : SegmentTree(end - begin, operation, operation_default_value,
                    modification, modification_default_value) {
    copy(begin, end, t.begin() + n);
    build();
  }

  void build() {
    for (i64 i = n - 1; i > 0; --i)
      t[i] = operation(t[i << 1], t[i << 1 | 1]);
  }

  void modify(i64 p, const T &value) {
    p += n;

    for (t[p] = modification(t[p], value); p > 1; p >>= 1)
      t[p >> 1] = operation(t[p], t[p ^ 1]);
  }

  T query(i64 l, i64 r) const { // [l, r)
    T res = operation_default_value;
    for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        res = operation(res, t[l++]);
      if (r & 1)
        res = operation(res, t[--r]);
    }
    return res;
  }
};

inline i64 factorial(i64 n) {
  i64 answer = 1;

  FORS(i, 2, 1 + n) {
    answer *= i;
    answer %= MODULO;
  }

  return answer;
}

inline i64 inv(i64 n) { return binpow(n, MODULO - 2, MODULO); }

inline i64 choose(i64 n, i64 k) {
  i64 answer = 1;

  FORS(i, n - k + 1, 1 + n) {
    answer *= i;
    answer %= MODULO;
  }

  answer *= inv(factorial(k));
  answer %= MODULO;

  return answer;
}

int main(int argc, const char *argv[]) {
#ifdef DEBUG
  assert(choose(4, 3) == 4);
#endif
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.precision(13);
  cout.setf(ios::fixed);
  srand((unsigned int)time(NULL));

  // enter your code here

  int n, a, b;

  while (scanf("%d%d%d", &n, &a, &b)) {
    printf("%d\n", int((binpow(2LL, n, MODULO) - 1 - choose(n, a) -
                        choose(n, b) + 3 * MODULO) %
                       MODULO));
  }

  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
// #pragma GCC target ("avx2")
// #pragma GCC optimization ("O3")
// #pragma GCC optimization ("unroll-loops")

#define clz __builtin_clzll
#define popcount __builtin_popcountll
#define FORS(i, s, n) for (i64 i = (s); i < (n); ++i)
#define RFORS(i, s, n) for (i64 i = (n)-1; i >= (s); --i)
#define FOR(i, n) FORS(i, 0, n)
#define RFOR(i, n) RFORS(i, 0, n)
#define FI(n) FOR(i, n)
#define RFI(n) RFOR(i, n)
#define ALL(x) (x).begin(), (x).end()
#define RALL(x) (x).rbegin(), (x).rend()
#define SZ(c) i64((c).size())
#define FOR_SETTED_BIT(bit, mask)                                              \
  for (int bit = 0; (mask) >> bit; ++bit)                                      \
    if (1 & (mask >> bit))
#define FOR_NONZERO_SUBMASK(submask, mask)                                     \
  for (int submask = (mask); submask; submask = (submask - 1) & (mask))
#define PI (3.141592653589793L)
#define MODULO ((i64)1e9 + 7LL)

using namespace std;

typedef int_fast8_t i8;
typedef int_fast16_t i16;
typedef int_fast32_t i32;
typedef int_fast64_t i64;
typedef uint_fast8_t u8;
typedef uint_fast16_t u16;
typedef uint_fast32_t u32;
typedef uint_fast64_t u64;
typedef pair<i64, i64> pi64;
typedef vector<i8> vb;
typedef vector<i32> vi32;
typedef vector<i64> vi64;
typedef vector<vi64> vvi64;
typedef vector<list<int>> AdjacencyLists;
typedef vector<list<pair<int, i64>>> WeightedAdjacencyLists;
typedef vvi64 AdjacencyMatrix;

template <class T> inline T sqr(const T &x) { return x * x; }
inline i64 sqr(int x) { return sqr<i64>(x); }
template <class T> T binpow(const T &a, i64 n) {
  return n == T(0) ? T(1) : sqr(binpow(a, n / 2)) * (n % 2 ? a : T(1));
}
i64 binpow(i64 a, i64 n, i64 modulo) {
  return n == 0 ? 1
                : sqr(binpow(a, n / 2, modulo)) % modulo * (n % 2 ? a : 1) %
                      modulo;
}
constexpr inline i64 phi(i64 n) {
  i64 result = n;
  for (i64 i = 2; i * i <= n; ++i)
    if (n % i == 0) {
      while (n % i == 0)
        n /= i;
      result -= result / i;
    }
  if (n > 1)
    result -= result / n;
  return result;
}

inline vi64 inverseAll(i64 m) {
  vi64 r(m);
  r[1] = 1;

  for (int i = 2; i < m; ++i)
    r[i] = (m - (m / i) * r[m % i] % m) % m;
  return r;
}
i64 gcd(i64 a, i64 b, i64 &x, i64 &y) {
  if (a == 0) {
    x = 0;
    y = 1;
    return b;
  }
  i64 x1, y1;
  i64 d = gcd(b % a, a, x1, y1);
  x = y1 - (b / a) * x1;
  y = x1;
  return d;
}
inline i64 gcd(i64 a, i64 b) { return gcd(a, b, a, b); }
inline i64 lcm(i64 a, i64 b) { return a / gcd(a, b) * b; }

template <class T, const T modulo, class TT = i64> class IntModulo {
  constexpr static const T order = phi(modulo);

  T value;

public:
  explicit IntModulo(const TT &value = 0)
      : value(T(((abs(value) + modulo - TT(1)) / modulo * modulo + value) %
                modulo)) {}

  inline IntModulo &operator+=(const IntModulo &i) {
    value = T((TT(value) + TT(i.value)) % modulo);
    return *this;
  }
  inline IntModulo &operator-=(const IntModulo &i) { return *this += -i; }
  inline IntModulo &operator*=(const IntModulo &i) {
    value = T((TT(value) * TT(i.value)) % modulo);
    return *this;
  }
  inline IntModulo &operator/=(const IntModulo &i) {
    return *this *= i.inverse();
  };

  inline IntModulo inverse() const { return binpow(*this, order - 1); };

  inline operator T() const { return value; }

  friend inline IntModulo operator-(const IntModulo &i) {
    return IntModulo<T, modulo, TT>(modulo - i.value);
  }

  friend inline bool operator==(const IntModulo &a, const IntModulo &b) {
    return a.value == b.value;
  }
};

template <class T, const T modulo, class TT = i64>
inline IntModulo<T, modulo, TT> operator+(const IntModulo<T, modulo, TT> &a,
                                          const IntModulo<T, modulo, TT> &b) {
  return IntModulo<T, modulo, TT>(a) += b;
}

template <class T, const T modulo, class TT = i64>
inline IntModulo<T, modulo, TT> operator-(const IntModulo<T, modulo, TT> &a,
                                          const IntModulo<T, modulo, TT> &b) {
  return IntModulo<T, modulo, TT>(a) -= b;
}

template <class T, const T modulo, class TT = i64>
inline IntModulo<T, modulo, TT> operator*(const IntModulo<T, modulo, TT> &a,
                                          const IntModulo<T, modulo, TT> &b) {
  return IntModulo<T, modulo, TT>(a) *= b;
}

template <class T, const T modulo, class TT = i64>
inline IntModulo<T, modulo, TT> operator/(const IntModulo<T, modulo, TT> &a,
                                          const IntModulo<T, modulo, TT> &b) {
  return IntModulo<T, modulo, TT>(a) /= b;
}

template <class T, const T modulo, class TT = i64>
inline bool operator!=(const IntModulo<T, modulo, TT> &a,
                       const IntModulo<T, modulo, TT> &b) {
  return !(a == b);
}

mt19937_64 rng(
#ifdef DEBUG
    0LL
#else
    chrono::steady_clock::now().time_since_epoch().count()
#endif
);
inline i64 random(i64 low, i64 high) {
  return uniform_int_distribution<i64>(low, high)(rng);
}
inline i64 random(i64 high = numeric_limits<i64>::max()) {
  return random(0, high);
}
#define rand random

struct Dinic {
  struct Edge {
    int u, v;
    i64 cap, flow;
    Edge() {}
    Edge(int u, int v, i64 cap) : u(u), v(v), cap(cap), flow(0) {}
  };

  int N;
  vector<Edge> E;
  vector<vector<int>> g;
  vector<int> d, pt;

  Dinic(int N) : N(N), E(0), g(N), d(N), pt(N) {}

  void AddEdge(int u, int v, i64 cap) {
    if (u != v) {
      E.emplace_back(Edge(u, v, cap));
      g[u].emplace_back(E.size() - 1);
      E.emplace_back(Edge(v, u, 0));
      g[v].emplace_back(E.size() - 1);
    }
  }

  bool BFS(int S, int T) {
    queue<int> q({S});
    fill(d.begin(), d.end(), N + 1);
    d[S] = 0;
    while (!q.empty()) {
      int u = q.front();
      q.pop();
      if (u == T)
        break;
      for (int k : g[u]) {
        Edge &e = E[k];
        if (e.flow < e.cap && d[e.v] > d[e.u] + 1) {
          d[e.v] = d[e.u] + 1;
          q.emplace(e.v);
        }
      }
    }
    return d[T] != N + 1;
  }

  i64 DFS(int u, int T, i64 flow = -1) {
    if (u == T || flow == 0)
      return flow;
    for (int &i = pt[u]; i < g[u].size(); ++i) {
      Edge &e = E[g[u][i]];
      Edge &oe = E[g[u][i] ^ 1];
      if (d[e.v] == d[e.u] + 1) {
        i64 amt = e.cap - e.flow;
        if (flow != -1 && amt > flow)
          amt = flow;
        if (i64 pushed = DFS(e.v, T, amt)) {
          e.flow += pushed;
          oe.flow -= pushed;
          return pushed;
        }
      }
    }
    return 0;
  }

  i64 MaxFlow(int S, int T) {
    i64 total = 0;
    while (BFS(S, T)) {
      fill(pt.begin(), pt.end(), 0);
      while (i64 flow = DFS(S, T))
        total += flow;
    }
    return total;
  }
};

vi64 Dijkstra(const WeightedAdjacencyLists &g, int s) {
  vi64 d(SZ(g), numeric_limits<i64>::max() / 2LL);
  priority_queue<pair<i64, int>> q;

  d[s] = 0;
  q.emplace(-0, s);

  while (!q.empty()) {
    if (q.top().first > d[q.top().second]) {
      q.pop();

      continue;
    }
    int v = q.top().second;

    q.pop();

    for (const auto &cw : g[v]) {
      if (d[v] + cw.second < d[cw.first]) {
        d[cw.first] = d[v] + cw.second;
        q.emplace(-d[cw.first], cw.first);
      }
    }
  }

  return d;
}

struct UnionFind {
  vi64 parent;
  vi64 rank;
  UnionFind(i64 n) : parent(n), rank(n) {
    for (i64 i = 0; i < n; ++i) {
      parent[i] = i;
      rank[i] = 0;
    }
  }
  i64 find_set(i64 v) {
    if (v == parent[v])
      return v;
    return parent[v] = find_set(parent[v]);
  }
  void union_sets(i64 a, i64 b) {
    a = find_set(a);
    b = find_set(b);
    if (a != b) {
      if (rank[a] < rank[b])
        swap(a, b);
      parent[b] = a;
      if (rank[a] == rank[b])
        ++rank[a];
    }
  }
};

// https://codeforces.com/blog/entry/18051
template <class T> const T assign(const T &a, const T &b) { return b; }

template <class T> const T &my_min(const T &a, const T &b) {
  return a < b ? a : b;
}

template <class T> struct SegmentTree {
  typedef function<T(T, T)> Function;

  const i64 n;
  vector<T> t;
  const function<T(const T &, const T &)> operation;
  const T &operation_default_value;
  const function<T(const T &, const T &)> modification;
  const T &modification_default_value;

  SegmentTree() {}

  SegmentTree(const i64 n, Function operation,
              const T &operation_default_value = T(),
              Function modification = assign<T>,
              const T &modification_default_value = T())
      : n(n), t(n << 1, operation_default_value), operation(operation),
        operation_default_value(operation_default_value),
        modification(modification),
        modification_default_value(modification_default_value) {
    build();
  }

  template <class Iterator>
  SegmentTree(const Iterator &begin, const Iterator &end, Function operation,
              const T &operation_default_value = T(),
              Function modification = assign<T>,
              const T &modification_default_value = T())
      : SegmentTree(end - begin, operation, operation_default_value,
                    modification, modification_default_value) {
    copy(begin, end, t.begin() + n);
    build();
  }

  void build() {
    for (i64 i = n - 1; i > 0; --i)
      t[i] = operation(t[i << 1], t[i << 1 | 1]);
  }

  void modify(i64 p, const T &value) {
    p += n;

    for (t[p] = modification(t[p], value); p > 1; p >>= 1)
      t[p >> 1] = operation(t[p], t[p ^ 1]);
  }

  T query(i64 l, i64 r) const { // [l, r)
    T res = operation_default_value;
    for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
      if (l & 1)
        res = operation(res, t[l++]);
      if (r & 1)
        res = operation(res, t[--r]);
    }
    return res;
  }
};

inline i64 factorial(i64 n) {
  i64 answer = 1;

  FORS(i, 2, 1 + n) {
    answer *= i;
    answer %= MODULO;
  }

  return answer;
}

inline i64 inv(i64 n) { return binpow(n, MODULO - 2, MODULO); }

inline i64 choose(i64 n, i64 k) {
  i64 answer = 1;

  FORS(i, n - k + 1, 1 + n) {
    answer *= i;
    answer %= MODULO;
  }

  answer *= inv(factorial(k));
  answer %= MODULO;

  return answer;
}

int main(int argc, const char *argv[]) {
#ifdef DEBUG
  assert(choose(4, 3) == 4);
#endif
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.precision(13);
  cout.setf(ios::fixed);
  srand((unsigned int)time(NULL));

  // enter your code here

  int n, a, b;

  while (~scanf("%d%d%d", &n, &a, &b)) {
    printf("%d\n", int((binpow(2LL, n, MODULO) - 1 - choose(n, a) -
                        choose(n, b) + 3 * MODULO) %
                       MODULO));
  }

  return 0;
}