Problem p03641 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <queue>
#define ls l, mid
#define rs mid + 1, r
#define lc p << 1
#define rc p << 1 | 1
#define mem(a, b) memset(a, b, sizeof(a))
#define For(i, a, b) for (int i = a, i##E = b; i <= i##E; ++i)
#define rFor(i, a, b) for (int i = a, i##E = b; i >= i##E; --i)
using namespace std;
typedef long long LL;
const int N = 200010;
const int inf = 0x3f3f3f3f;
template <typename T> inline T chkmax(T A, T B) { return A > B ? A : B; }
template <typename T> inline T chkmin(T A, T B) { return A < B ? A : B; }
template <typename T> inline void read(T &x) {
  x = 0;
  int _f(0);
  char ch = getchar();
  while (!isdigit(ch))
    _f |= (ch == '-'), ch = getchar();
  while (isdigit(ch))
    x = x * 10 + ch - '0', ch = getchar();
  x = _f ? -x : x;
}
inline void file() {
#ifndef ONLINE_JUDGE
  freopen("in.txt", "r", stdin);
  freopen("out.txt", "w", stdout);
#endif
}
int n, a[N], p[N], len;
int t[N << 2][2], b[N], tot;
inline void Build_tree(int l, int r, int p, int x) {
  if (l == r) {
    t[p][x] = a[l * 2 - x];
    // printf("%d (%d %d) %d\n",p,l,r,t[p][x]);
    return;
  }
  int mid = (l + r) >> 1;
  Build_tree(ls, lc, x);
  Build_tree(rs, rc, x);
  t[p][x] = chkmin(t[lc][x], t[rc][x]);
  // printf("%d (%d %d) %d\n",p,l,r,t[p][x]);
}
inline int Query(int l, int r, int p, int x, int y, int z) {
  if (x <= l && r <= y)
    return t[p][z];
  int mid = (l + r) >> 1, Min = inf;
  if (x <= mid)
    Min = chkmin(Min, Query(ls, lc, x, y, z));
  if (y > mid)
    Min = chkmin(Min, Query(rs, rc, x, y, z));
  return Min;
}
struct node {
  int l, r, x, y;
  node() {}
  node(int l, int r, int x, int y) : l(l), r(r), x(x), y(y) {}
};
inline bool operator<(node A, node B) { return a[A.x] > a[B.x]; }
int main() {
  file();
  read(n);
  For(i, 1, n) read(a[i]), p[a[i]] = i;
  len = n / 2;
  Build_tree(1, len, 1, 0);
  Build_tree(1, len, 1, 1);
  priority_queue<node> q;
  node now;
  now.l = 1;
  now.r = n;
  now.x = p[Query(1, len, 1, 1, len, 1)];
  now.y = p[Query(1, len, 1, (now.x + 1) / 2, len, 0)];
  q.push(now);
  while (!q.empty()) {
    node now = q.top();
    q.pop();
    // printf("%d %d %d %d\n",now.l,now.r,now.x,now.y);
    b[++tot] = a[now.x];
    b[++tot] = a[now.y];
    node nxt;
    nxt.l = now.l;
    nxt.r = now.x - 1;
    if (nxt.l < nxt.r) {
      if (nxt.l & 1) {
        nxt.x = p[Query(1, len, 1, (nxt.l + 1) >> 1, (nxt.r) >> 1, 1)];
        nxt.y = p[Query(1, len, 1, (nxt.x + 1) >> 1, (nxt.r) >> 1, 0)];
      } else {
        nxt.x = p[Query(1, len, 1, nxt.l >> 1, nxt.r >> 1, 0)];
        nxt.y = p[Query(1, len, 1, (nxt.x + 2) >> 1, (nxt.r + 1) >> 1, 1)];
      }
      q.push(nxt);
    }
    nxt.l = now.x + 1;
    nxt.r = now.y - 1;
    if (nxt.l < nxt.r) {
      if (nxt.l & 1) {
        nxt.x = p[Query(1, len, 1, (nxt.l + 1) >> 1, (nxt.r) >> 1, 1)];
        nxt.y = p[Query(1, len, 1, (nxt.x + 1) >> 1, (nxt.r) >> 1, 0)];
      } else {
        nxt.x = p[Query(1, len, 1, nxt.l >> 1, nxt.r >> 1, 0)];
        nxt.y = p[Query(1, len, 1, (nxt.x + 2) >> 1, (nxt.r + 1) >> 1, 1)];
      }
      q.push(nxt);
    }
    nxt.l = now.y + 1;
    nxt.r = now.r;
    if (nxt.l < nxt.r) {
      if (nxt.l & 1) {
        nxt.x = p[Query(1, len, 1, (nxt.l + 1) >> 1, (nxt.r) >> 1, 1)];
        nxt.y = p[Query(1, len, 1, (nxt.x + 1) >> 1, (nxt.r) >> 1, 0)];
      } else {
        nxt.x = p[Query(1, len, 1, nxt.l >> 1, nxt.r >> 1, 0)];
        nxt.y = p[Query(1, len, 1, (nxt.x + 2) >> 1, (nxt.r + 1) >> 1, 1)];
      }
      q.push(nxt);
    }
  }
  For(i, 1, tot) printf("%d ", b[i]);
  return 0;
}


Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <queue>
#define ls l, mid
#define rs mid + 1, r
#define lc p << 1
#define rc p << 1 | 1
#define mem(a, b) memset(a, b, sizeof(a))
#define For(i, a, b) for (int i = a, i##E = b; i <= i##E; ++i)
#define rFor(i, a, b) for (int i = a, i##E = b; i >= i##E; --i)
using namespace std;
typedef long long LL;
const int N = 200010;
const int inf = 0x3f3f3f3f;
template <typename T> inline T chkmax(T A, T B) { return A > B ? A : B; }
template <typename T> inline T chkmin(T A, T B) { return A < B ? A : B; }
template <typename T> inline void read(T &x) {
  x = 0;
  int _f(0);
  char ch = getchar();
  while (!isdigit(ch))
    _f |= (ch == '-'), ch = getchar();
  while (isdigit(ch))
    x = x * 10 + ch - '0', ch = getchar();
  x = _f ? -x : x;
}
inline void file() {
#ifndef ONLINE_JUDGE
  freopen("in.txt", "r", stdin);
  freopen("out.txt", "w", stdout);
#endif
}
int n, a[N], p[N], len;
int t[N << 2][2], b[N], tot;
inline void Build_tree(int l, int r, int p, int x) {
  if (l == r) {
    t[p][x] = a[l * 2 - x];
    // printf("%d (%d %d) %d\n",p,l,r,t[p][x]);
    return;
  }
  int mid = (l + r) >> 1;
  Build_tree(ls, lc, x);
  Build_tree(rs, rc, x);
  t[p][x] = chkmin(t[lc][x], t[rc][x]);
  // printf("%d (%d %d) %d\n",p,l,r,t[p][x]);
}
inline int Query(int l, int r, int p, int x, int y, int z) {
  if (x <= l && r <= y)
    return t[p][z];
  int mid = (l + r) >> 1, Min = inf;
  if (x <= mid)
    Min = chkmin(Min, Query(ls, lc, x, y, z));
  if (y > mid)
    Min = chkmin(Min, Query(rs, rc, x, y, z));
  return Min;
}
struct node {
  int l, r, x, y;
  node() {}
  node(int l, int r, int x, int y) : l(l), r(r), x(x), y(y) {}
};
inline bool operator<(node A, node B) { return a[A.x] > a[B.x]; }
int main() {
  read(n);
  For(i, 1, n) read(a[i]), p[a[i]] = i;
  len = n / 2;
  Build_tree(1, len, 1, 0);
  Build_tree(1, len, 1, 1);
  priority_queue<node> q;
  node now;
  now.l = 1;
  now.r = n;
  now.x = p[Query(1, len, 1, 1, len, 1)];
  now.y = p[Query(1, len, 1, (now.x + 1) / 2, len, 0)];
  q.push(now);
  while (!q.empty()) {
    node now = q.top();
    q.pop();
    // printf("%d %d %d %d\n",now.l,now.r,now.x,now.y);
    b[++tot] = a[now.x];
    b[++tot] = a[now.y];
    node nxt;
    nxt.l = now.l;
    nxt.r = now.x - 1;
    if (nxt.l < nxt.r) {
      if (nxt.l & 1) {
        nxt.x = p[Query(1, len, 1, (nxt.l + 1) >> 1, (nxt.r) >> 1, 1)];
        nxt.y = p[Query(1, len, 1, (nxt.x + 1) >> 1, (nxt.r) >> 1, 0)];
      } else {
        nxt.x = p[Query(1, len, 1, nxt.l >> 1, nxt.r >> 1, 0)];
        nxt.y = p[Query(1, len, 1, (nxt.x + 2) >> 1, (nxt.r + 1) >> 1, 1)];
      }
      q.push(nxt);
    }
    nxt.l = now.x + 1;
    nxt.r = now.y - 1;
    if (nxt.l < nxt.r) {
      if (nxt.l & 1) {
        nxt.x = p[Query(1, len, 1, (nxt.l + 1) >> 1, (nxt.r) >> 1, 1)];
        nxt.y = p[Query(1, len, 1, (nxt.x + 1) >> 1, (nxt.r) >> 1, 0)];
      } else {
        nxt.x = p[Query(1, len, 1, nxt.l >> 1, nxt.r >> 1, 0)];
        nxt.y = p[Query(1, len, 1, (nxt.x + 2) >> 1, (nxt.r + 1) >> 1, 1)];
      }
      q.push(nxt);
    }
    nxt.l = now.y + 1;
    nxt.r = now.r;
    if (nxt.l < nxt.r) {
      if (nxt.l & 1) {
        nxt.x = p[Query(1, len, 1, (nxt.l + 1) >> 1, (nxt.r) >> 1, 1)];
        nxt.y = p[Query(1, len, 1, (nxt.x + 1) >> 1, (nxt.r) >> 1, 0)];
      } else {
        nxt.x = p[Query(1, len, 1, nxt.l >> 1, nxt.r >> 1, 0)];
        nxt.y = p[Query(1, len, 1, (nxt.x + 2) >> 1, (nxt.r + 1) >> 1, 1)];
      }
      q.push(nxt);
    }
  }
  For(i, 1, tot) printf("%d ", b[i]);
  return 0;
}