Problem p03641 (C++)

Buggy submission (status: Time Limit Exceeded):
#define _USE_MATH_DEFINES
#include <algorithm>
#include <climits>
#include <cmath>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <queue>
#include <stack>
#include <string>
#include <tuple>
#include <vector>

#define int long long
#define CONTAINS(v, n) (find((v).begin(), (v).end(), (n)) != (v).end())
#define SORT(v) sort((v).begin(), (v).end())
#define RSORT(v) sort((v).rbegin(), (v).rend())
#define ARY_SORT(a, size) sort((a), (a) + (size))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define REMOVE(v, a) v.erase(remove(v.begin(), v.end(), a), v.end())
#define REP(i, n) for (int(i) = 0; (i) < (n); (i)++)
using namespace std;

int N;
int p[200000];

struct SegSt {
public:
  int n;
  int index;
  SegSt() {}
  SegSt(int n, int index) {
    this->n = n;
    this->index = index;
  }
};

const int SEG_MAX = (1 << 17);
SegSt seg[2][SEG_MAX * 2];

void Set(int s, int index, SegSt st) {
  int k = (SEG_MAX - 1) + index; // 底
  seg[s][k] = st;
  while (true) {
    k = (k - 1) / 2;
    if (st.n < seg[s][k].n) {
      seg[s][k] = st;
    }
    if (k == 0)
      break;
  }
}

SegSt GetMin(int s, int a, int b, int k = 0, int l = 0, int r = SEG_MAX) {
  if (l >= b || a >= r) {
    return SegSt(INT_MAX, INT_MAX);
  }

  if (a <= l && r <= b) {
    return seg[s][k];
  } else {
    SegSt ll = GetMin(s, a, b, k * 2 + 1, l, (l + r) / 2);
    SegSt rr = GetMin(s, a, b, k * 2 + 2, (l + r) / 2, r);
    if (ll.n < rr.n) {
      return ll;
    } else {
      return rr;
    }
  }
}

struct St {
public:
  int l;
  int r;
  int min;
  St(int l, int r, int min) {
    this->l = l;
    this->r = r;
    this->min = min;
  }
  bool operator<(const St &st) const { return st.min < min; }
};

signed main() {
  cin >> N;
  memset(seg, 1, sizeof(seg));
  REP(i, N) {
    cin >> p[i];
    Set(i % 2, i, SegSt(p[i], i));
  }

  priority_queue<St> q;
  q.push(St(0, N, GetMin(0, 0, N).n));

  list<int> ans;

  while (q.size() > 0) {
    St st = q.top();
    q.pop();
    int s = st.l % 2;
    SegSt seg_st1 = GetMin(s, st.l, st.r);
    int i = seg_st1.index;
    int ss = (s + 1) % 2;
    SegSt seg_st2 = GetMin(ss, i + 1, st.r);
    int j = seg_st2.index;
    if (i - st.l > 0) {
      q.push(St(st.l, i, GetMin(st.l % 2, st.l, i).n));
    }
    if (j - (i + 1) > 0) {
      q.push(St(i + 1, j, GetMin((i + 1) % 2, i + 1, j).n));
    }
    if (st.r - (j + 1) > 0) {
      q.push(St(j + 1, st.r, GetMin((j + 1) % 2, j + 1, st.r).n));
    }
    ans.push_back(seg_st1.n);
    ans.push_back(seg_st2.n);
  }

  for (int n : ans) {
    cout << n << " ";
  }
  cout << endl;
}

Fixed submission:
#define _USE_MATH_DEFINES
#include <algorithm>
#include <climits>
#include <cmath>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <queue>
#include <stack>
#include <string>
#include <tuple>
#include <vector>

#define int long long
#define CONTAINS(v, n) (find((v).begin(), (v).end(), (n)) != (v).end())
#define SORT(v) sort((v).begin(), (v).end())
#define RSORT(v) sort((v).rbegin(), (v).rend())
#define ARY_SORT(a, size) sort((a), (a) + (size))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define REMOVE(v, a) v.erase(remove(v.begin(), v.end(), a), v.end())
#define REP(i, n) for (int(i) = 0; (i) < (n); (i)++)
using namespace std;

int N;
int p[200000];

struct SegSt {
public:
  int n;
  int index;
  SegSt() {}
  SegSt(int n, int index) {
    this->n = n;
    this->index = index;
  }
};

const int SEG_MAX = (1 << 18);
SegSt seg[2][SEG_MAX * 2];

void Set(int s, int index, SegSt st) {
  int k = (SEG_MAX - 1) + index; // 底
  seg[s][k] = st;
  while (true) {
    k = (k - 1) / 2;
    if (st.n < seg[s][k].n) {
      seg[s][k] = st;
    }
    if (k == 0)
      break;
  }
}

SegSt GetMin(int s, int a, int b, int k = 0, int l = 0, int r = SEG_MAX) {
  if (l >= b || a >= r) {
    return SegSt(INT_MAX, INT_MAX);
  }

  if (a <= l && r <= b) {
    return seg[s][k];
  } else {
    SegSt ll = GetMin(s, a, b, k * 2 + 1, l, (l + r) / 2);
    SegSt rr = GetMin(s, a, b, k * 2 + 2, (l + r) / 2, r);
    if (ll.n < rr.n) {
      return ll;
    } else {
      return rr;
    }
  }
}

struct St {
public:
  int l;
  int r;
  int min;
  St(int l, int r, int min) {
    this->l = l;
    this->r = r;
    this->min = min;
  }
  bool operator<(const St &st) const { return st.min < min; }
};

signed main() {
  cin >> N;
  memset(seg, 1, sizeof(seg));
  REP(i, N) {
    cin >> p[i];
    Set(i % 2, i, SegSt(p[i], i));
  }

  priority_queue<St> q;
  q.push(St(0, N, GetMin(0, 0, N).n));

  list<int> ans;

  while (q.size() > 0) {
    St st = q.top();
    q.pop();
    int s = st.l % 2;
    SegSt seg_st1 = GetMin(s, st.l, st.r);
    int i = seg_st1.index;
    int ss = (s + 1) % 2;
    SegSt seg_st2 = GetMin(ss, i + 1, st.r);
    int j = seg_st2.index;
    if (i - st.l > 0) {
      q.push(St(st.l, i, GetMin(st.l % 2, st.l, i).n));
    }
    if (j - (i + 1) > 0) {
      q.push(St(i + 1, j, GetMin((i + 1) % 2, i + 1, j).n));
    }
    if (st.r - (j + 1) > 0) {
      q.push(St(j + 1, st.r, GetMin((j + 1) % 2, j + 1, st.r).n));
    }
    ans.push_back(seg_st1.n);
    ans.push_back(seg_st2.n);
  }

  for (int n : ans) {
    cout << n << " ";
  }
  cout << endl;
}