Problem p03641 (C++)

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

template <typename T> void out(T x) {
  cout << x << endl;
  exit(0);
}
#define watch(x) cout << (#x) << " is " << (x) << endl

typedef long long ll;
const ll mod = 1e9 + 7;
const int maxn = 1e6 + 5;

const int inf = 1e9;

struct sparse_table {
  // 0-indexed, init with vector.

  // todo: call init()
  const static int LOG = 18; // todo
  int n;
  vector<int> a[LOG + 1];
  vector<int> lg_floor;

  // todo
  int eval(int x, int y) { return min(x, y); }

  // todo: ll vs int
  void init(vector<int> v) {
    n = v.size();
    lg_floor.resize(n + 10);
    lg_floor[1] = 0;
    for (int i = 2; i < n + 10; i++)
      lg_floor[i] = 1 + lg_floor[i / 2];
    for (int j = 0; j < LOG; j++)
      a[j].resize(n);
    for (int i = 0; i < n; i++)
      a[0][i] = v[i];

    for (int j = 1; j < LOG; j++) {
      for (int i = 0; i < n; i++) {
        a[j][i] = a[j - 1][i];
        if (i + (1 << (j - 1)) < n) {
          a[j][i] = eval(a[j][i], a[j - 1][i + (1 << (j - 1))]);
        }
      }
    }
  }

  int get(int l, int r) {
    assert(l <= r);
    int lg = lg_floor[r - l + 1];

    return eval(a[lg][l], a[lg][r - (1 << lg) + 1]);
  }
};

int n;
vector<int> a, evens, odds;
sparse_table st_a, st_evens, st_odds;
map<int, int> ai;

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n;
  a.resize(n);
  for (int i = 0; i < n; i++) {
    cin >> a[i];
    ai[a[i]] = i;
  }
  evens = a;
  odds = a;
  for (int i = 1; i < n; i += 2)
    evens[i] = inf;
  for (int i = 0; i < n; i += 2)
    odds[i] = inf;

  st_a.init(a);
  st_evens.init(evens);
  st_odds.init(odds);

  priority_queue<pair<int, pair<int, int>>> pq; //{lo, {l,r}}

  pq.push({-st_evens.get(0, n - 1), {0, n - 1}});

  auto add = [&](int l, int r) {
    if (l > r)
      return;
    assert((r - l + 1) % 2 == 0);
    int lo = l % 2 == 0 ? st_evens.get(l, r) : st_odds.get(l, r);
    pq.push({-lo, {l, r}});
  };

  vector<int> ans;

  while (!pq.empty()) {
    auto cur = pq.top();
    pq.pop();
    int x = -cur.first;
    int l = cur.second.first;
    int r = cur.second.second;
    int i = ai[x];

    assert((r - l + 1) % 2 == 0);

    int y = i % 2 == 0 ? st_odds.get(l, r) : st_evens.get(l, r);
    int j = ai[y];
    assert(i < j);

    ans.push_back(x);
    ans.push_back(y);

    add(l, i - 1);
    add(i + 1, j - 1);
    add(j + 1, r);
  }

  for (int x : ans)
    cout << x << " ";
  cout << endl;

  return 0;
}


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

template <typename T> void out(T x) {
  cout << x << endl;
  exit(0);
}
#define watch(x) cout << (#x) << " is " << (x) << endl

typedef long long ll;
const ll mod = 1e9 + 7;
const int maxn = 1e6 + 5;

const int inf = 1e9;

struct sparse_table {
  // 0-indexed, init with vector.

  // todo: call init()
  const static int LOG = 18; // todo
  int n;
  vector<int> a[LOG + 1];
  vector<int> lg_floor;

  // todo
  int eval(int x, int y) { return min(x, y); }

  // todo: ll vs int
  void init(vector<int> v) {
    n = v.size();
    lg_floor.resize(n + 10);
    lg_floor[1] = 0;
    for (int i = 2; i < n + 10; i++)
      lg_floor[i] = 1 + lg_floor[i / 2];
    for (int j = 0; j < LOG; j++)
      a[j].resize(n);
    for (int i = 0; i < n; i++)
      a[0][i] = v[i];

    for (int j = 1; j < LOG; j++) {
      for (int i = 0; i < n; i++) {
        a[j][i] = a[j - 1][i];
        if (i + (1 << (j - 1)) < n) {
          a[j][i] = eval(a[j][i], a[j - 1][i + (1 << (j - 1))]);
        }
      }
    }
  }

  int get(int l, int r) {
    assert(l <= r);
    int lg = lg_floor[r - l + 1];

    return eval(a[lg][l], a[lg][r - (1 << lg) + 1]);
  }
};

int n;
vector<int> a, evens, odds;
sparse_table st_a, st_evens, st_odds;
map<int, int> ai;

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n;
  a.resize(n);
  for (int i = 0; i < n; i++) {
    cin >> a[i];
    ai[a[i]] = i;
  }
  evens = a;
  odds = a;
  for (int i = 1; i < n; i += 2)
    evens[i] = inf;
  for (int i = 0; i < n; i += 2)
    odds[i] = inf;

  st_a.init(a);
  st_evens.init(evens);
  st_odds.init(odds);

  priority_queue<pair<int, pair<int, int>>> pq; //{lo, {l,r}}

  pq.push({-st_evens.get(0, n - 1), {0, n - 1}});

  auto add = [&](int l, int r) {
    if (l > r)
      return;
    assert((r - l + 1) % 2 == 0);
    int lo = l % 2 == 0 ? st_evens.get(l, r) : st_odds.get(l, r);
    pq.push({-lo, {l, r}});
  };

  vector<int> ans;

  while (!pq.empty()) {
    auto cur = pq.top();
    pq.pop();
    int x = -cur.first;
    int l = cur.second.first;
    int r = cur.second.second;
    int i = ai[x];

    assert((r - l + 1) % 2 == 0);

    int y = i % 2 == 0 ? st_odds.get(i, r) : st_evens.get(i, r);
    int j = ai[y];
    assert(i < j);

    ans.push_back(x);
    ans.push_back(y);

    add(l, i - 1);
    add(i + 1, j - 1);
    add(j + 1, r);
  }

  for (int x : ans)
    cout << x << " ";
  cout << endl;

  return 0;
}