Problem p02956 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define MOD 998244353LL
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<P, int> PP;

class segtree {
public:
  static const int N = 1 << 18;
  int dp[1 << 19];
  segtree() { memset(dp, 0, sizeof(dp)); }
  void update(int k, int v) {
    k += N - 1;
    dp[k] += v;
    while (k > 0) {
      k = (k - 1) / 2;
      dp[k] = dp[k * 2 + 1] + dp[k * 2 + 2];
    }
  }

  int query(int a, int b, int k = 0, int l = 0, int r = N) {
    if (b <= l || r <= a)
      return 0;
    if (a <= l && r <= b)
      return dp[k];
    int mid = (l + r) / 2;
    int vl = query(a, b, k * 2 + 1, l, mid);
    int vr = query(a, b, k * 2 + 2, mid, r);
    return vl + vr;
  }
};

int n;
int x[200005], y[200005];
vector<int> xi;
vector<int> yi;
int cnt[2][100005][2];
segtree seg;
PP p[200005];

ll mod_pow(ll x, ll n) {
  ll ans = 1;
  while (n > 0) {
    if (n & 1) {
      ans = ans * x % MOD;
    }
    x = x * x % MOD;
    n >>= 1;
  }
  return ans;
}

int main(void) {
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    scanf("%lld%lld", &x[i], &y[i]);
    xi.push_back(x[i]);
    yi.push_back(y[i]);
  }
  sort(xi.begin(), xi.end());
  sort(yi.begin(), yi.end());

  for (int i = 0; i < n; i++) {
    x[i] = lower_bound(xi.begin(), xi.end(), x[i]) - xi.begin();
    y[i] = lower_bound(yi.begin(), yi.end(), y[i]) - yi.begin();
    p[i].first = P(x[i], y[i]);
    p[i].second = i;
  }
  sort(p, p + n);
  for (int i = 0; i < n; i++) {
    int v = p[i].second;
    cnt[0][v][0] = seg.query(0, p[i].first.second);
    cnt[0][v][1] = seg.query(p[i].first.second, n);
    seg.update(p[i].first.second, 1);
  }
  memset(seg.dp, 0, sizeof(seg.dp));
  for (int i = n - 1; i >= 0; i--) {
    int v = p[i].second;
    cnt[1][v][0] = seg.query(0, p[i].first.second);
    cnt[1][v][1] = seg.query(p[i].first.second, n);
    seg.update(p[i].first.second, 1);
  }
  ll ans = (ll)n * mod_pow(2, n - 1) % MOD;
  for (int i = 0; i < n; i++) {
    // printf("%lld %d %d %d
    // %d\n",ans,cnt[0][i][0],cnt[0][i][1],cnt[1][i][0],cnt[1][i][1]);
    ll val = (mod_pow(2, cnt[0][i][0]) - 1LL) *
             (mod_pow(2, cnt[1][i][1]) - 1LL) % MOD;
    ll val2 = (mod_pow(2, cnt[0][i][1]) - 1LL) *
              (mod_pow(2, cnt[1][i][0]) - 1LL) % MOD;
    ans += MOD - (val * val2) % MOD;
    ans %= MOD;
    ans += val * mod_pow(2, cnt[0][i][1] + cnt[1][i][0]) % MOD;
    ans %= MOD;
    ans += val2 * mod_pow(2, cnt[0][i][0] + cnt[1][i][1]) % MOD;
    ans %= MOD;
  }
  printf("%lld\n", ans);
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#define MOD 998244353LL
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<P, int> PP;

class segtree {
public:
  static const int N = 1 << 18;
  int dp[1 << 19];
  segtree() { memset(dp, 0, sizeof(dp)); }
  void update(int k, int v) {
    k += N - 1;
    dp[k] += v;
    while (k > 0) {
      k = (k - 1) / 2;
      dp[k] = dp[k * 2 + 1] + dp[k * 2 + 2];
    }
  }

  int query(int a, int b, int k = 0, int l = 0, int r = N) {
    if (b <= l || r <= a)
      return 0;
    if (a <= l && r <= b)
      return dp[k];
    int mid = (l + r) / 2;
    int vl = query(a, b, k * 2 + 1, l, mid);
    int vr = query(a, b, k * 2 + 2, mid, r);
    return vl + vr;
  }
};

int n;
int x[200005], y[200005];
vector<int> xi;
vector<int> yi;
int cnt[2][200005][2];
segtree seg;
PP p[200005];

ll mod_pow(ll x, ll n) {
  ll ans = 1;
  while (n > 0) {
    if (n & 1) {
      ans = ans * x % MOD;
    }
    x = x * x % MOD;
    n >>= 1;
  }
  return ans;
}

int main(void) {
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    scanf("%lld%lld", &x[i], &y[i]);
    xi.push_back(x[i]);
    yi.push_back(y[i]);
  }
  sort(xi.begin(), xi.end());
  sort(yi.begin(), yi.end());

  for (int i = 0; i < n; i++) {
    x[i] = lower_bound(xi.begin(), xi.end(), x[i]) - xi.begin();
    y[i] = lower_bound(yi.begin(), yi.end(), y[i]) - yi.begin();
    p[i].first = P(x[i], y[i]);
    p[i].second = i;
  }
  sort(p, p + n);
  for (int i = 0; i < n; i++) {
    int v = p[i].second;
    cnt[0][v][0] = seg.query(0, p[i].first.second);
    cnt[0][v][1] = seg.query(p[i].first.second, n);
    seg.update(p[i].first.second, 1);
  }
  memset(seg.dp, 0, sizeof(seg.dp));
  for (int i = n - 1; i >= 0; i--) {
    int v = p[i].second;
    cnt[1][v][0] = seg.query(0, p[i].first.second);
    cnt[1][v][1] = seg.query(p[i].first.second, n);
    seg.update(p[i].first.second, 1);
  }
  ll ans = (ll)n * mod_pow(2, n - 1) % MOD;
  for (int i = 0; i < n; i++) {
    // printf("%lld %d %d %d
    // %d\n",ans,cnt[0][i][0],cnt[0][i][1],cnt[1][i][0],cnt[1][i][1]);
    ll val = (mod_pow(2, cnt[0][i][0]) - 1LL) *
             (mod_pow(2, cnt[1][i][1]) - 1LL) % MOD;
    ll val2 = (mod_pow(2, cnt[0][i][1]) - 1LL) *
              (mod_pow(2, cnt[1][i][0]) - 1LL) % MOD;
    ans += MOD - (val * val2) % MOD;
    ans %= MOD;
    ans += val * mod_pow(2, cnt[0][i][1] + cnt[1][i][0]) % MOD;
    ans %= MOD;
    ans += val2 * mod_pow(2, cnt[0][i][0] + cnt[1][i][1]) % MOD;
    ans %= MOD;
  }
  printf("%lld\n", ans);
  return 0;
}