Problem p03641 (C++)

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

const int MAX_N = 1 << 17;
const int def = 1 << 25;
const int INF = 1 << 25;

typedef pair<int, int> Node;
struct MinSegTreeIdx {
  int n;
  Node node[2 * MAX_N - 1];

  void init(int n_) {
    n = 1;
    while (n < n_)
      n *= 2;
    for (int i = 0; i < 2 * n - 1; i++)
      node[i] = make_pair(def, def);
  }

  Node merge(Node l, Node r) {
    if (l.first <= r.first)
      return l;
    return r;
  }

  void update(int k, int a) {
    k += n - 1;
    node[k] = make_pair(a, k - (n - 1));
    while (k > 0) {
      k = (k - 1) / 2;
      node[k] = merge(node[k * 2 + 1], node[k * 2 + 2]);
    }
  }

  Node query(int a, int b) { return query(a, b, 0, 0, n); }

  Node query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return make_pair(def, def);
    if (a <= l && r <= b)
      return node[k];
    Node vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
    Node vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return merge(vl, vr);
  }

  void show() {
    for (int i = 0; i < n; i++)
      cout << node[i + n - 1].first << " ";
    cout << endl;
  }
};

int a[200000];
MinSegTreeIdx even, odd;
int N;
set<int> s;

typedef pair<int, int> P;
typedef pair<P, int> Pi;

vector<P> ps;
vector<int> children[200000];

Pi f(int L, int R) {
  int len = R - L;
  if (len <= 0) {
    return {{-1, -1}, -1};
  }

  int id = ps.size();
  ps.push_back({-1, -1});

  if (len == 2) {
    ps[id] = {a[L], a[L + 1]};
    return {ps[id], id};
  }

  MinSegTreeIdx *st1 = &even;
  MinSegTreeIdx *st2 = &odd;
  if (L % 2 == 1) {
    st1 = &odd;
    st2 = &even;
  }

  auto res1 = st1->query(L, R - 1);
  // cout << res1.first << " " << res1.second << endl;
  int l = res1.second;
  int right = *s.upper_bound(l);
  auto res2 = st2->query(l + 1, right);
  // cout << res2.first << " " << res2.second << endl;
  int r = res2.second;

  s.insert(l);
  s.insert(r);

  auto k1 = f(L, l), k2 = f(l + 1, r), k3 = f(r + 1, R);
  if (k1.second != -1)
    children[id].push_back(k1.second);
  if (k2.second != -1)
    children[id].push_back(k2.second);
  if (k3.second != -1)
    children[id].push_back(k3.second);

  // st1->update(l, INF);
  // st1->update(r, INF);
  // st2->update(l, INF);
  // st2->update(r, INF);

  ps[id] = {a[l], a[r]};
  return {ps[id], id};
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  cin >> N;

  even.init(N);
  odd.init(N);

  for (int i = 0; i < N; i++) {
    cin >> a[i];
    if (i % 2 == 0) {
      even.update(i, a[i]);
      odd.update(i, INF);
    } else {
      even.update(i, INF);
      odd.update(i, a[i]);
    }
  }
  // even.show();
  // odd.show();

  s.insert(N);

  deque<int> ans;
  priority_queue<Pi, vector<Pi>, greater<Pi>> q;
  auto res = f(0, N);
  q.push(res);
  while (q.size()) {
    auto pi = q.top();
    q.pop();
    ans.push_back(pi.first.first);
    ans.push_back(pi.first.second);
    int id = pi.second;
    for (auto c : children[id]) {
      q.push({ps[c], c});
    }
  }

  for (int i = 0; i < N; i++) {
    cout << ans[i] << " ";
  }
  cout << endl;
}


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

const int MAX_N = 1 << 19;
const int def = 1 << 25;
const int INF = 1 << 25;

typedef pair<int, int> Node;
struct MinSegTreeIdx {
  int n;
  Node node[2 * MAX_N - 1];

  void init(int n_) {
    n = 1;
    while (n < n_)
      n *= 2;
    for (int i = 0; i < 2 * n - 1; i++)
      node[i] = make_pair(def, def);
  }

  Node merge(Node l, Node r) {
    if (l.first <= r.first)
      return l;
    return r;
  }

  void update(int k, int a) {
    k += n - 1;
    node[k] = make_pair(a, k - (n - 1));
    while (k > 0) {
      k = (k - 1) / 2;
      node[k] = merge(node[k * 2 + 1], node[k * 2 + 2]);
    }
  }

  Node query(int a, int b) { return query(a, b, 0, 0, n); }

  Node query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l)
      return make_pair(def, def);
    if (a <= l && r <= b)
      return node[k];
    Node vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
    Node vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return merge(vl, vr);
  }

  void show() {
    for (int i = 0; i < n; i++)
      cout << node[i + n - 1].first << " ";
    cout << endl;
  }
};

int a[200000];
MinSegTreeIdx even, odd;
int N;
set<int> s;

typedef pair<int, int> P;
typedef pair<P, int> Pi;

vector<P> ps;
vector<int> children[200000];

Pi f(int L, int R) {
  int len = R - L;
  if (len <= 0) {
    return {{-1, -1}, -1};
  }

  int id = ps.size();
  ps.push_back({-1, -1});

  if (len == 2) {
    ps[id] = {a[L], a[L + 1]};
    return {ps[id], id};
  }

  MinSegTreeIdx *st1 = &even;
  MinSegTreeIdx *st2 = &odd;
  if (L % 2 == 1) {
    st1 = &odd;
    st2 = &even;
  }

  auto res1 = st1->query(L, R - 1);
  // cout << res1.first << " " << res1.second << endl;
  int l = res1.second;
  int right = *s.upper_bound(l);
  auto res2 = st2->query(l + 1, right);
  // cout << res2.first << " " << res2.second << endl;
  int r = res2.second;

  s.insert(l);
  s.insert(r);

  auto k1 = f(L, l), k2 = f(l + 1, r), k3 = f(r + 1, R);
  if (k1.second != -1)
    children[id].push_back(k1.second);
  if (k2.second != -1)
    children[id].push_back(k2.second);
  if (k3.second != -1)
    children[id].push_back(k3.second);

  // st1->update(l, INF);
  // st1->update(r, INF);
  // st2->update(l, INF);
  // st2->update(r, INF);

  ps[id] = {a[l], a[r]};
  return {ps[id], id};
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  cin >> N;

  even.init(N);
  odd.init(N);

  for (int i = 0; i < N; i++) {
    cin >> a[i];
    if (i % 2 == 0) {
      even.update(i, a[i]);
      odd.update(i, INF);
    } else {
      even.update(i, INF);
      odd.update(i, a[i]);
    }
  }
  // even.show();
  // odd.show();

  s.insert(N);

  deque<int> ans;
  priority_queue<Pi, vector<Pi>, greater<Pi>> q;
  auto res = f(0, N);
  q.push(res);
  while (q.size()) {
    auto pi = q.top();
    q.pop();
    ans.push_back(pi.first.first);
    ans.push_back(pi.first.second);
    int id = pi.second;
    for (auto c : children[id]) {
      q.push({ps[c], c});
    }
  }

  for (int i = 0; i < N; i++) {
    cout << ans[i] << " ";
  }
  cout << endl;
}