Problem p02956 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <tuple>
#include <vector>

const long long mod = 998244353;

auto max_bit(int32_t n) {
  n = n & 0xFFFF0000 ? n & 0xFFFF0000 : n;
  n = n & 0xFF00FF00 ? n & 0xFF00FF00 : n;
  n = n & 0xF0F0F0F0 ? n & 0xF0F0F0F0 : n;
  n = n & 0xCCCCCCCC ? n & 0xCCCCCCCC : n;
  n = n & 0xAAAAAAAA ? n & 0xAAAAAAAA : n;
  return n;
}

template <typename T> class Segtree {
  int nbin;
  const T param_def;
  std::vector<T> seg_vec;
  std::function<T(T, T)> seg_func;
  T query_partial(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return param_def;
    if (a <= l && r <= b)
      return seg_vec[k];
    const T v_l = query_partial(a, b, k * 2 + 1, l, (l + r) / 2);
    const T v_r = query_partial(a, b, k * 2 + 2, (l + r) / 2, r);
    return seg_func(v_l, v_r);
  }

public:
  Segtree(const std::vector<T> &data, const std::function<T(T, T)> &_seg_func,
          const T _param_def)
      : seg_func(_seg_func), param_def(_param_def) {
    nbin = max_bit(data.size() - 1) * 2;
    seg_vec.resize(nbin * 2 - 1, param_def);
    auto insert_top = seg_vec.begin();
    insert_top += nbin - 1;
    std::copy(data.cbegin(), data.cend(), insert_top);
    for (int i = nbin - 2; i >= 0; i--) {
      seg_vec[i] = seg_func(seg_vec[i * 2 + 1], seg_vec[i * 2 + 2]);
    }
  }
  T get(int i) { return seg_vec[nbin - 1 + i]; }
  void update(int i, int x) {
    i += nbin - 1;
    seg_vec[i] = x;
    while (i > 0) {
      i = (i - 1) / 2;
      seg_vec[i] = seg_func(seg_vec[i * 2 + 1], seg_vec[i * 2 + 2]);
    }
  }
  T query(int a, int b) { return query_partial(a, b, 0, 0, nbin); }
};

long long mod_pow2(long long n) {
  long long ans = 1, np = 2;
  while (n > 0) {
    if (n & 1)
      ans = (ans * np) % mod;
    np = (np * np) % mod;
    n >>= 1;
  }
  return ans;
}

int main() {
  int N;
  std::cin >> N;

  std::vector<std::tuple<int, int>> xy_arr;
  std::map<int, int> y_map;

  for (int i = 0; i < N; i++) {
    int x, y;
    std::cin >> x >> y;
    y_map[y] = 0;
    xy_arr.emplace_back(x, y);
  }

  int ni = 0;
  for (auto &&it : y_map) {
    it.second = ni;
    ni++;
  }

  std::vector<std::tuple<int, int, int, int>> p_arr(N);
  auto f_sum = [](int l, int r) { return l + r; };
  Segtree<int> seg1(std::vector<int>(N), f_sum, 0),
      seg2(std::vector<int>(N), f_sum, 0);
  std::sort(xy_arr.begin(), xy_arr.end());
  for (int i = 0; i < N; i++) {
    int y2 = y_map[std::get<1>(xy_arr[i])];
    std::get<0>(p_arr[i]) = seg1.query(0, y2);
    std::get<1>(p_arr[i]) = seg1.query(y2, ni);
    seg1.update(y2, 1);
  }
  std::sort(xy_arr.rbegin(), xy_arr.rend());
  for (int i = 0; i < N; i++) {
    int y2 = y_map[std::get<1>(xy_arr[i])];
    std::get<2>(p_arr[N - 1 - i]) = seg2.query(0, y2);
    std::get<3>(p_arr[N - 1 - i]) = seg2.query(y2, ni);
    seg2.update(y2, 1);
  }
  long long ans = 0;
  for (int i = 0; i < N; i++) {
    long long a, b, c, d;
    std::tie(a, b, c, d) = p_arr[i];
    long long a2 = mod_pow2(a);
    long long b2 = mod_pow2(b);
    long long c2 = mod_pow2(c);
    long long d2 = mod_pow2(d);
    ans += (((((a2 * b2) % mod) * c2) % mod) * d2) % mod;
    ans += ((((((a2 - 1) * (d2 - 1)) % mod) * b2) % mod) * c2) % mod;
    ans += ((((a2 + d2 - 1) * (b2 - 1)) % mod) * (c2 - 1)) % mod;
    ans %= mod;
  }
  ans = ((ans % mod) + mod) % mod;

  std::cout << ans << std::endl;

  return 0;
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <tuple>
#include <vector>

const long long mod = 998244353;

auto max_bit(int32_t n) {
  n = n & 0xFFFF0000 ? n & 0xFFFF0000 : n;
  n = n & 0xFF00FF00 ? n & 0xFF00FF00 : n;
  n = n & 0xF0F0F0F0 ? n & 0xF0F0F0F0 : n;
  n = n & 0xCCCCCCCC ? n & 0xCCCCCCCC : n;
  n = n & 0xAAAAAAAA ? n & 0xAAAAAAAA : n;
  return n;
}

template <typename T> class Segtree {
  int nbin;
  const T param_def;
  std::vector<T> seg_vec;
  std::function<T(T, T)> seg_func;
  T query_partial(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return param_def;
    if (a <= l && r <= b)
      return seg_vec[k];
    const T v_l = query_partial(a, b, k * 2 + 1, l, (l + r) / 2);
    const T v_r = query_partial(a, b, k * 2 + 2, (l + r) / 2, r);
    return seg_func(v_l, v_r);
  }

public:
  Segtree(const std::vector<T> &data, const std::function<T(T, T)> &_seg_func,
          const T _param_def)
      : seg_func(_seg_func), param_def(_param_def) {
    nbin = max_bit(data.size() - 1) * 2;
    seg_vec.resize(nbin * 2 - 1, param_def);
    auto insert_top = seg_vec.begin();
    insert_top += nbin - 1;
    std::copy(data.cbegin(), data.cend(), insert_top);
    for (int i = nbin - 2; i >= 0; i--) {
      seg_vec[i] = seg_func(seg_vec[i * 2 + 1], seg_vec[i * 2 + 2]);
    }
  }
  T get(int i) { return seg_vec[nbin - 1 + i]; }
  void update(int i, int x) {
    i += nbin - 1;
    seg_vec[i] = x;
    while (i > 0) {
      i = (i - 1) / 2;
      seg_vec[i] = seg_func(seg_vec[i * 2 + 1], seg_vec[i * 2 + 2]);
    }
  }
  T query(int a, int b) { return query_partial(a, b, 0, 0, nbin); }
};

long long mod_pow2(long long n) {
  long long ans = 1, np = 2;
  while (n > 0) {
    if (n & 1)
      ans = (ans * np) % mod;
    np = (np * np) % mod;
    n >>= 1;
  }
  return ans;
}

int main() {
  int N;
  std::cin >> N;

  std::vector<std::tuple<int, int>> xy_arr;
  std::map<int, int> y_map;

  for (int i = 0; i < N; i++) {
    int x, y;
    std::cin >> x >> y;
    y_map[y] = 0;
    xy_arr.emplace_back(x, y);
  }

  int ni = 0;
  for (auto &&it : y_map) {
    it.second = ni;
    ni++;
  }

  if (N == 1) {
    std::cout << 1 << std::endl;
    return 0;
  }

  std::vector<std::tuple<int, int, int, int>> p_arr(N);
  auto f_sum = [](int l, int r) { return l + r; };
  Segtree<int> seg1(std::vector<int>(N), f_sum, 0),
      seg2(std::vector<int>(N), f_sum, 0);
  std::sort(xy_arr.begin(), xy_arr.end());
  for (int i = 0; i < N; i++) {
    int y2 = y_map[std::get<1>(xy_arr[i])];
    std::get<0>(p_arr[i]) = seg1.query(0, y2);
    std::get<1>(p_arr[i]) = seg1.query(y2, ni);
    seg1.update(y2, 1);
  }
  std::sort(xy_arr.rbegin(), xy_arr.rend());
  for (int i = 0; i < N; i++) {
    int y2 = y_map[std::get<1>(xy_arr[i])];
    std::get<2>(p_arr[N - 1 - i]) = seg2.query(0, y2);
    std::get<3>(p_arr[N - 1 - i]) = seg2.query(y2, ni);
    seg2.update(y2, 1);
  }
  long long ans = 0;
  for (int i = 0; i < N; i++) {
    long long a, b, c, d;
    std::tie(a, b, c, d) = p_arr[i];
    long long a2 = mod_pow2(a);
    long long b2 = mod_pow2(b);
    long long c2 = mod_pow2(c);
    long long d2 = mod_pow2(d);
    ans += (((((a2 * b2) % mod) * c2) % mod) * d2) % mod;
    ans += ((((((a2 - 1) * (d2 - 1)) % mod) * b2) % mod) * c2) % mod;
    ans += ((((a2 + d2 - 1) * (b2 - 1)) % mod) * (c2 - 1)) % mod;
    ans %= mod;
  }
  ans = ((ans % mod) + mod) % mod;

  std::cout << ans << std::endl;

  return 0;
}