Problem p03641 (C++)

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

typedef long long LL;
typedef long double LD;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<LD, LD> PDD;

#define _upgrade                                                               \
  ios_base::sync_with_stdio(0);                                                \
  cin.tie(0);                                                                  \
  cout.tie(0);
#define all(x) (x).begin(), (x).end()
#define sz(x) (int)(x).size()
template <typename _T> inline void _DBG(const char *s, _T x) {
  cerr << s << " = " << x << "\n";
}
template <typename _T, typename... args>
void _DBG(const char *s, _T x, args... a) {
  while (*s != ',')
    cerr << *s++;
  cerr << " = " << x << ',';
  _DBG(s + 1, a...);
}

#ifdef LOCAL
#define DBG(...) _DBG(#__VA_ARGS__, __VA_ARGS__)
#else
#define DBG(...) (__VA_ARGS__)
#define cerr                                                                   \
  if (0)                                                                       \
  cout
#endif

// ********************** CODE ********************** //

const int N = 1e5 + 7;
const int INF = 1e9 + 7;
const int MAX = 1 << 18;

PII tree[2 * MAX + 7];
int lazy[2 * MAX + 7];

inline void propagate(int node, int l, int r) {
  if (lazy[node]) {
    swap(tree[node].first, tree[node].second);
    if (l != r) {
      lazy[2 * node] ^= 1;
      lazy[2 * node + 1] ^= 1;
    }
    lazy[node] = 0;
  }
}

void update(int a, int b, int node = 1, int l = 0, int r = MAX - 1) {
  propagate(node, l, r);
  if (b < l || r < a)
    return;
  if (a <= l && r <= b) {
    lazy[node] ^= 1;
    propagate(node, l, r);
    return;
  }
  update(a, b, 2 * node, l, (l + r) / 2);
  update(a, b, 2 * node + 1, (l + r) / 2 + 1, r);
  tree[node].first = min(tree[2 * node].first, tree[2 * node + 1].first);
  tree[node].second = min(tree[2 * node].second, tree[2 * node + 1].second);
}

void erase(int e, int node = 1, int l = 0, int r = MAX - 1) {
  propagate(node, l, r);
  if (e < l || r < e)
    return;
  if (l == r) {
    tree[node].first = tree[node].second = INF;
    return;
  }
  int m = (l + r) / 2;
  erase(e, 2 * node, l, m);
  erase(e, 2 * node + 1, m + 1, r);
  tree[node].first = min(tree[2 * node].first, tree[2 * node + 1].first);
  tree[node].second = min(tree[2 * node].second, tree[2 * node + 1].second);
}

PII query(int a, int b, int node = 1, int l = 0, int r = MAX - 1) {
  propagate(node, l, r);
  if (b < l || r < a)
    return {INF, INF};
  if (a <= l && r <= b)
    return tree[node];
  PII x = query(a, b, 2 * node, l, (l + r) / 2);
  PII y = query(a, b, 2 * node + 1, (l + r) / 2 + 1, r);
  return {min(x.first, y.first), min(x.second, y.second)};
}

int n, p[N], g[N];
set<int> zero;

int main() {
  _upgrade cin >> n;
  for (int i = 0; i < 2 * MAX + 7; i++)
    tree[i].first = tree[i].second = INF;
  for (int i = 0; i < n; i++) {
    cin >> p[i];
    g[p[i]] = i;
    tree[i + MAX] = {p[i], INF};
    if (i & 1)
      swap(tree[i + MAX].first, tree[i + MAX].second);
  }
  for (int node = MAX - 1; node; node--) {
    tree[node].first = min(tree[2 * node].first, tree[2 * node + 1].first);
    tree[node].second = min(tree[2 * node].second, tree[2 * node + 1].second);
  }
  zero.insert(n);
  for (int i = 1; 2 * i <= n; i++) {
    int x = tree[1].first;
    int val = *zero.lower_bound(g[x]);
    int y = query(g[x], val).second;
    update(g[x], g[y]);
    cout << x << " " << y << " ";
    erase(g[x]);
    erase(g[y]);
    zero.insert(g[x]);
    zero.insert(g[y]);
  }
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef long double LD;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<LD, LD> PDD;

#define _upgrade                                                               \
  ios_base::sync_with_stdio(0);                                                \
  cin.tie(0);                                                                  \
  cout.tie(0);
#define all(x) (x).begin(), (x).end()
#define sz(x) (int)(x).size()
template <typename _T> inline void _DBG(const char *s, _T x) {
  cerr << s << " = " << x << "\n";
}
template <typename _T, typename... args>
void _DBG(const char *s, _T x, args... a) {
  while (*s != ',')
    cerr << *s++;
  cerr << " = " << x << ',';
  _DBG(s + 1, a...);
}

#ifdef LOCAL
#define DBG(...) _DBG(#__VA_ARGS__, __VA_ARGS__)
#else
#define DBG(...) (__VA_ARGS__)
#define cerr                                                                   \
  if (0)                                                                       \
  cout
#endif

// ********************** CODE ********************** //

const int N = 2e5 + 7;
const int INF = 1e9 + 7;
const int MAX = 1 << 18;

PII tree[2 * MAX + 7];
int lazy[2 * MAX + 7];

inline void propagate(int node, int l, int r) {
  if (lazy[node]) {
    swap(tree[node].first, tree[node].second);
    if (l != r) {
      lazy[2 * node] ^= 1;
      lazy[2 * node + 1] ^= 1;
    }
    lazy[node] = 0;
  }
}

void update(int a, int b, int node = 1, int l = 0, int r = MAX - 1) {
  propagate(node, l, r);
  if (b < l || r < a)
    return;
  if (a <= l && r <= b) {
    lazy[node] ^= 1;
    propagate(node, l, r);
    return;
  }
  update(a, b, 2 * node, l, (l + r) / 2);
  update(a, b, 2 * node + 1, (l + r) / 2 + 1, r);
  tree[node].first = min(tree[2 * node].first, tree[2 * node + 1].first);
  tree[node].second = min(tree[2 * node].second, tree[2 * node + 1].second);
}

void erase(int e, int node = 1, int l = 0, int r = MAX - 1) {
  propagate(node, l, r);
  if (e < l || r < e)
    return;
  if (l == r) {
    tree[node].first = tree[node].second = INF;
    return;
  }
  int m = (l + r) / 2;
  erase(e, 2 * node, l, m);
  erase(e, 2 * node + 1, m + 1, r);
  tree[node].first = min(tree[2 * node].first, tree[2 * node + 1].first);
  tree[node].second = min(tree[2 * node].second, tree[2 * node + 1].second);
}

PII query(int a, int b, int node = 1, int l = 0, int r = MAX - 1) {
  propagate(node, l, r);
  if (b < l || r < a)
    return {INF, INF};
  if (a <= l && r <= b)
    return tree[node];
  PII x = query(a, b, 2 * node, l, (l + r) / 2);
  PII y = query(a, b, 2 * node + 1, (l + r) / 2 + 1, r);
  return {min(x.first, y.first), min(x.second, y.second)};
}

int n, p[N], g[N];
set<int> zero;

int main() {
  _upgrade cin >> n;
  for (int i = 0; i < 2 * MAX + 7; i++)
    tree[i].first = tree[i].second = INF;
  for (int i = 0; i < n; i++) {
    cin >> p[i];
    g[p[i]] = i;
    tree[i + MAX] = {p[i], INF};
    if (i & 1)
      swap(tree[i + MAX].first, tree[i + MAX].second);
  }
  for (int node = MAX - 1; node; node--) {
    tree[node].first = min(tree[2 * node].first, tree[2 * node + 1].first);
    tree[node].second = min(tree[2 * node].second, tree[2 * node + 1].second);
  }
  zero.insert(n);
  for (int i = 1; 2 * i <= n; i++) {
    int x = tree[1].first;
    int val = *zero.lower_bound(g[x]);
    int y = query(g[x], val).second;
    update(g[x], g[y]);
    cout << x << " " << y << " ";
    erase(g[x]);
    erase(g[y]);
    zero.insert(g[x]);
    zero.insert(g[y]);
  }
  return 0;
}