Problem p02956 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

using namespace std;

using i64 = int64_t;

const i64 MOD = (i64)1e9 + 7;

const i64 INF = (i64)1e18 + 7;

template <typename T = i64> struct Range {
  struct iterator {
    T value;
    const T step, last;
    const T &operator*() { return value; }
    iterator(T value, T step, T last)
        : value(step < static_cast<T>(0) ? max(last, value) : min(last, value)),
          step(step), last(last) {}
    iterator operator++() {
      value = step < static_cast<T>(0) ? max(value + step, last)
                                       : min(value + step, last);
      return *this;
    }
    bool operator!=(const iterator &x) { return value != x.value; }
  };
  const T start, last, step;

  Range(const T start, const T last, const T step = static_cast<T>(1))
      : start(start), last(last), step(step) {}

  Range(const T last) : start(0), last(last), step(1) {}

  iterator begin() { return iterator(start, step, last); }
  iterator end() { return iterator(last, step, last); }
};

template <typename F> struct FixPoint {
  const F _f;
  FixPoint(F &&f) : _f(forward<F>(f)) {}

  template <typename... Types>
  decltype(auto) operator()(Types &&...args) const {
    return _f(*this, forward<Types>(args)...);
  }
};

template <typename F> static decltype(auto) makeRec(F &&f) {
  return FixPoint<F>(forward<F>(f));
}

template <typename T, T Value = T()> vector<T> makeVector(size_t x) {
  return vector<T>(x, T(Value));
}

template <typename T, T Value = T(), typename... Types>
auto makeVector(size_t x, Types... args) {
  return vector<decltype(makeVector<T, Value>(args...))>(
      x, makeVector<T, Value>(args...));
}

template <typename T = i64> bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

template <typename T = i64> bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

#ifdef TEST
#define dump(x)                                                                \
  fprintf(stderr, "line =%4d, name =%7s , ", __LINE__, #x);                    \
  cout << "value = " << x << endl;
#define vecdump(x)                                                             \
  fprintf(stderr, "line =%4d, name =%7s\n", __LINE__, #x);                     \
  _dump_macro(x);
#else
#define vecdump(x)
#define dump(x)
#endif

void _dump(int, string &x) {
#ifdef TEST
  cout << x << endl;
#endif
}

template <typename T> void _dump(bool, T &x) {
#ifdef TEST
  cout << x << " ";
#endif
}

template <typename T, typename U = typename T::iterator> void _dump(int, T &x) {
#ifdef TEST
  for (auto &elm : x)
    _dump(0, elm);

  cout << endl;
#endif
}

template <typename T> void _dump_macro(T &x) { _dump(0, x); }

void _input(int, string &x) { cin >> x; }

template <typename T> void _input(bool, T &x) { cin >> x; }

template <typename T, typename U = typename T::iterator>
void _input(int, T &x) {

  for (auto &elm : x)
    _input(0, elm);
}

template <typename T> void input_single(T &x) { _input(0, x); }

auto input() {}

template <typename T, typename... Types> void input(T &value, Types &&...args) {
  input_single(value);
  input(forward<Types>(args)...);
};

void _pararell_input(size_t) {}

template <typename T, typename... Types>
void _pararell_input(size_t index, T &value, Types &&...args) {
  input(value[index]);
  _pararell_input(index, forward<Types>(args)...);
}

template <typename... Types>
void pararell_input(size_t count, Types &&...args) {
  for (const auto &i : Range<>(count))
    _pararell_input(i, forward<Types>(args)...);
}

template <typename T> struct Segtree {
  int n;
  T op;
  vector<T> elm;
  function<T(T, T)> f;

  Segtree(int n, T init, function<T(T, T)> f, T op = T())
      : n(n), op(op), elm(2 * n, init), f(f) {
    for (int i = n - 1; i >= 1; --i)
      elm[i] = f(elm[2 * i], elm[2 * i + 1]);
  }

  Segtree(int n, vector<T> init, function<T(T, T)> f, T op = T())
      : n(n), op(op), elm(2 * n), f(f) {
    for (int i = 0; i < n; ++i)
      elm[i + n] = init[i];
    for (int i = n - 1; i >= 1; --i)
      elm[i] = f(elm[2 * i], elm[2 * i + 1]);
  }

  void set(int x, T val) {
    x += n;
    elm[x] = val;
    while (x >>= 1)
      elm[x] = f(elm[2 * x], elm[2 * x + 1]);
  }

  void update(int x, T val) {
    x += n;
    elm[x] = f(val, elm[x]);
    while (x >>= 1)
      elm[x] = f(elm[2 * x], elm[2 * x + 1]);
  }

  T get(int x, int y) const {
    T l = op, r = op;
    for (x += n, y += n - 1; x <= y; x >>= 1, y >>= 1) {
      if (x & 1)
        l = f(l, elm[x++]);
      if (!(y & 1))
        r = f(elm[y--], r);
    }
    return f(l, r);
  }
};

template <typename T> struct Compression {
  vector<T> compvec;
  Compression(vector<T> &inp) { // 圧縮する
    compvec = inp;
    sort(compvec.begin(), compvec.end());
    compvec.erase(unique(compvec.begin(), compvec.end()), compvec.end());
  }
  int Index(T val) { // 圧縮を元に対応するインデックスを返す
    auto it = lower_bound(compvec.begin(), compvec.end(), val);
    return distance(compvec.begin(), it);
  }
  vector<T> &operator*() { return compvec; }
};

template <i64 mod = MOD> struct ModInt {
  i64 p;

  ModInt() : p(0) {}
  ModInt(i64 x) { p = x >= 0 ? x % mod : x + (-x + mod - 1) / mod * mod; }

  ModInt &operator+=(const ModInt &y) {
    p = p + *y - ((p + *y) >= mod ? mod : 0);
    return *this;
  }
  ModInt &operator-=(const ModInt &y) {
    p = p - *y + (p - *y < 0 ? mod : 0);
    return *this;
  }
  ModInt &operator*=(const ModInt &y) {
    p = (p * *y) % mod;
    return *this;
  }
  ModInt &operator%=(const ModInt &y) {
    if (y)
      p %= *y;
    return *this;
  }

  ModInt operator+(const ModInt &y) const {
    ModInt x = *this;
    return x += y;
  }
  ModInt operator-(const ModInt &y) const {
    ModInt x = *this;
    return x -= y;
  }
  ModInt operator*(const ModInt &y) const {
    ModInt x = *this;
    return x *= y;
  }
  ModInt operator%(const ModInt &y) const {
    ModInt x = *this;
    return x %= y;
  }

  friend ostream &operator<<(ostream &stream, const ModInt<mod> &x) {
    stream << *x;
    return stream;
  }

  friend ostream &operator>>(ostream &stream, const ModInt<mod> &x) {
    stream >> *x;
    return stream;
  }

  ModInt &operator++() {
    p = (p + 1) % mod;
    return *this;
  }
  ModInt &operator--() {
    p = (p - 1 + mod) % mod;
    return *this;
  }

  bool operator==(const ModInt &y) const { return p == *y; }
  bool operator!=(const ModInt &y) const { return p != *y; }

  const i64 &operator*() const { return p; }
  i64 &operator*() { return p; }
};

using mint = ModInt<998244353>;

i64 solve(i64 _count) {

  int n;
  input(n);

  if (!static_cast<bool>(cin))
    return MOD;
#ifdef TEST
  cout << "Case: " << _count << endl;
#endif

  vector<i64> x(n), y(n);
  pararell_input(n, x, y);

  vector<pair<i64, i64>> v;
  for (int i = 0; i < n; ++i)
    v.emplace_back(x[i], y[i]);
  sort(v.begin(), v.end());

  vector<mint> tp(n + 3, 1);
  for (int i = 0; i < n + 3; ++i)
    tp[i + 1] = tp[i] * 2;

  Compression<i64> comp(y);
  Segtree<int> seg_up(
      n, 1, [](auto x, auto y) { return x + y; }, 0);
  Segtree<int> seg_down(
      n, 0, [](auto x, auto y) { return x + y; }, 0);
  mint ans(0);
  for (auto &p : v) {
    int idx = comp.Index(p.second);
    seg_up.set(idx, 0);

    i64 p1 = seg_up.get(0, idx);
    i64 p2 = seg_up.get(idx, n);
    i64 p3 = seg_down.get(0, idx);
    i64 p4 = seg_down.get(idx, n);

    mint val = 1;
    val *= tp[p1] - 1;
    val *= tp[p4] - 1;
    ans += val * tp[n - p1 - p4 - 1];

    val = 1;
    val *= tp[p2] - 1;
    val *= tp[p3] - 1;
    ans += val * tp[n - p2 - p3 - 1];

    val = 1;
    val *= tp[p1] - 1;
    val *= tp[p2] - 1;
    val *= tp[p3] - 1;
    val *= tp[p4] - 1;
    ans -= val;

    ans += tp[n - 1];

    seg_down.set(idx, 1);
  }

  cout << ans << endl;

  return 0;
}

signed main() {

  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(20);

  int t = 0;
  while (solve(++t) != MOD)
    ;
}


Fixed submission:
#include <bits/stdc++.h>

using namespace std;

using i64 = int64_t;

const i64 MOD = (i64)1e9 + 7;

const i64 INF = (i64)1e18 + 7;

template <typename T = i64> struct Range {
  struct iterator {
    T value;
    const T step, last;
    const T &operator*() { return value; }
    iterator(T value, T step, T last)
        : value(step < static_cast<T>(0) ? max(last, value) : min(last, value)),
          step(step), last(last) {}
    iterator operator++() {
      value = step < static_cast<T>(0) ? max(value + step, last)
                                       : min(value + step, last);
      return *this;
    }
    bool operator!=(const iterator &x) { return value != x.value; }
  };
  const T start, last, step;

  Range(const T start, const T last, const T step = static_cast<T>(1))
      : start(start), last(last), step(step) {}

  Range(const T last) : start(0), last(last), step(1) {}

  iterator begin() { return iterator(start, step, last); }
  iterator end() { return iterator(last, step, last); }
};

template <typename F> struct FixPoint {
  const F _f;
  FixPoint(F &&f) : _f(forward<F>(f)) {}

  template <typename... Types>
  decltype(auto) operator()(Types &&...args) const {
    return _f(*this, forward<Types>(args)...);
  }
};

template <typename F> static decltype(auto) makeRec(F &&f) {
  return FixPoint<F>(forward<F>(f));
}

template <typename T, T Value = T()> vector<T> makeVector(size_t x) {
  return vector<T>(x, T(Value));
}

template <typename T, T Value = T(), typename... Types>
auto makeVector(size_t x, Types... args) {
  return vector<decltype(makeVector<T, Value>(args...))>(
      x, makeVector<T, Value>(args...));
}

template <typename T = i64> bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

template <typename T = i64> bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

#ifdef TEST
#define dump(x)                                                                \
  fprintf(stderr, "line =%4d, name =%7s , ", __LINE__, #x);                    \
  cout << "value = " << x << endl;
#define vecdump(x)                                                             \
  fprintf(stderr, "line =%4d, name =%7s\n", __LINE__, #x);                     \
  _dump_macro(x);
#else
#define vecdump(x)
#define dump(x)
#endif

void _dump(int, string &x) {
#ifdef TEST
  cout << x << endl;
#endif
}

template <typename T> void _dump(bool, T &x) {
#ifdef TEST
  cout << x << " ";
#endif
}

template <typename T, typename U = typename T::iterator> void _dump(int, T &x) {
#ifdef TEST
  for (auto &elm : x)
    _dump(0, elm);

  cout << endl;
#endif
}

template <typename T> void _dump_macro(T &x) { _dump(0, x); }

void _input(int, string &x) { cin >> x; }

template <typename T> void _input(bool, T &x) { cin >> x; }

template <typename T, typename U = typename T::iterator>
void _input(int, T &x) {

  for (auto &elm : x)
    _input(0, elm);
}

template <typename T> void input_single(T &x) { _input(0, x); }

auto input() {}

template <typename T, typename... Types> void input(T &value, Types &&...args) {
  input_single(value);
  input(forward<Types>(args)...);
};

void _pararell_input(size_t) {}

template <typename T, typename... Types>
void _pararell_input(size_t index, T &value, Types &&...args) {
  input(value[index]);
  _pararell_input(index, forward<Types>(args)...);
}

template <typename... Types>
void pararell_input(size_t count, Types &&...args) {
  for (const auto &i : Range<>(count))
    _pararell_input(i, forward<Types>(args)...);
}

template <typename T> struct Segtree {
  int n;
  T op;
  vector<T> elm;
  function<T(T, T)> f;

  Segtree(int n, T init, function<T(T, T)> f, T op = T())
      : n(n), op(op), elm(2 * n, init), f(f) {
    for (int i = n - 1; i >= 1; --i)
      elm[i] = f(elm[2 * i], elm[2 * i + 1]);
  }

  Segtree(int n, vector<T> init, function<T(T, T)> f, T op = T())
      : n(n), op(op), elm(2 * n), f(f) {
    for (int i = 0; i < n; ++i)
      elm[i + n] = init[i];
    for (int i = n - 1; i >= 1; --i)
      elm[i] = f(elm[2 * i], elm[2 * i + 1]);
  }

  void set(int x, T val) {
    x += n;
    elm[x] = val;
    while (x >>= 1)
      elm[x] = f(elm[2 * x], elm[2 * x + 1]);
  }

  void update(int x, T val) {
    x += n;
    elm[x] = f(val, elm[x]);
    while (x >>= 1)
      elm[x] = f(elm[2 * x], elm[2 * x + 1]);
  }

  T get(int x, int y) const {
    T l = op, r = op;
    for (x += n, y += n - 1; x <= y; x >>= 1, y >>= 1) {
      if (x & 1)
        l = f(l, elm[x++]);
      if (!(y & 1))
        r = f(elm[y--], r);
    }
    return f(l, r);
  }
};

template <typename T> struct Compression {
  vector<T> compvec;
  Compression(vector<T> &inp) { // 圧縮する
    compvec = inp;
    sort(compvec.begin(), compvec.end());
    compvec.erase(unique(compvec.begin(), compvec.end()), compvec.end());
  }
  int Index(T val) { // 圧縮を元に対応するインデックスを返す
    auto it = lower_bound(compvec.begin(), compvec.end(), val);
    return distance(compvec.begin(), it);
  }
  vector<T> &operator*() { return compvec; }
};

template <i64 mod = MOD> struct ModInt {
  i64 p;

  ModInt() : p(0) {}
  ModInt(i64 x) { p = x >= 0 ? x % mod : x + (-x + mod - 1) / mod * mod; }

  ModInt &operator+=(const ModInt &y) {
    p = p + *y - ((p + *y) >= mod ? mod : 0);
    return *this;
  }
  ModInt &operator-=(const ModInt &y) {
    p = p - *y + (p - *y < 0 ? mod : 0);
    return *this;
  }
  ModInt &operator*=(const ModInt &y) {
    p = (p * *y) % mod;
    return *this;
  }
  ModInt &operator%=(const ModInt &y) {
    if (y)
      p %= *y;
    return *this;
  }

  ModInt operator+(const ModInt &y) const {
    ModInt x = *this;
    return x += y;
  }
  ModInt operator-(const ModInt &y) const {
    ModInt x = *this;
    return x -= y;
  }
  ModInt operator*(const ModInt &y) const {
    ModInt x = *this;
    return x *= y;
  }
  ModInt operator%(const ModInt &y) const {
    ModInt x = *this;
    return x %= y;
  }

  friend ostream &operator<<(ostream &stream, const ModInt<mod> &x) {
    stream << *x;
    return stream;
  }

  friend ostream &operator>>(ostream &stream, const ModInt<mod> &x) {
    stream >> *x;
    return stream;
  }

  ModInt &operator++() {
    p = (p + 1) % mod;
    return *this;
  }
  ModInt &operator--() {
    p = (p - 1 + mod) % mod;
    return *this;
  }

  bool operator==(const ModInt &y) const { return p == *y; }
  bool operator!=(const ModInt &y) const { return p != *y; }

  const i64 &operator*() const { return p; }
  i64 &operator*() { return p; }
};

using mint = ModInt<998244353>;

i64 solve(i64 _count) {

  int n;
  input(n);

  if (!static_cast<bool>(cin))
    return MOD;
#ifdef TEST
  cout << "Case: " << _count << endl;
#endif

  vector<i64> x(n), y(n);
  pararell_input(n, x, y);

  vector<pair<i64, i64>> v;
  for (int i = 0; i < n; ++i)
    v.emplace_back(x[i], y[i]);
  sort(v.begin(), v.end());

  vector<mint> tp(n + 3, 1);
  for (int i = 0; i < n + 2; ++i)
    tp[i + 1] = tp[i] * 2;

  Compression<i64> comp(y);
  Segtree<int> seg_up(
      n, 1, [](auto x, auto y) { return x + y; }, 0);
  Segtree<int> seg_down(
      n, 0, [](auto x, auto y) { return x + y; }, 0);
  mint ans(0);
  for (auto &p : v) {
    int idx = comp.Index(p.second);
    seg_up.set(idx, 0);

    i64 p1 = seg_up.get(0, idx);
    i64 p2 = seg_up.get(idx, n);
    i64 p3 = seg_down.get(0, idx);
    i64 p4 = seg_down.get(idx, n);

    mint val = 1;
    val *= tp[p1] - 1;
    val *= tp[p4] - 1;
    ans += val * tp[n - p1 - p4 - 1];

    val = 1;
    val *= tp[p2] - 1;
    val *= tp[p3] - 1;
    ans += val * tp[n - p2 - p3 - 1];

    val = 1;
    val *= tp[p1] - 1;
    val *= tp[p2] - 1;
    val *= tp[p3] - 1;
    val *= tp[p4] - 1;
    ans -= val;

    ans += tp[n - 1];

    seg_down.set(idx, 1);
  }

  cout << ans << endl;

  return 0;
}

signed main() {

  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(20);

  int t = 0;
  while (solve(++t) != MOD)
    ;
}