Problem p03235 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
#define LL long long
#define LD long double
using namespace std;
const int NN = 200000 + 117;
const int MM = 200000 + 117;
int read() {
  int fl = 1, x;
  char c;
  for (c = getchar(); (c < '0' || c > '9') && c != '-'; c = getchar())
    ;
  if (c == '-') {
    fl = -1;
    c = getchar();
  }
  for (x = 0; c >= '0' && c <= '9'; c = getchar())
    x = (x << 3) + (x << 1) + c - '0';
  return x * fl;
}
void open() {
  freopen("a.in", "r", stdin);
  // freopen("a.out","w",stdout);
}
void close() {
  fclose(stdin);
  fclose(stdout);
}

int m, n;
bool mark[NN] = {};
int suf[NN] = {};
struct seg {
  int ev, od;
  int s[2];
} t[20 * NN] = {};
int tcnt = 0;
int a[NN] = {};
int rt[NN] = {};
int op[NN] = {};
void push_up(int pos) {
  int ls = t[pos].s[0];
  int rs = t[pos].s[1];
  t[pos].ev = max(t[ls].ev, t[rs].ev);
  t[pos].od = max(t[ls].od, t[rs].od);
}
int build(int l, int r) {
  int pos = ++tcnt;
  if (l == r) {
    t[pos].ev = 0;
    t[pos].od = -1e9 + 1;
    return pos;
  }
  int mid = (l + r) >> 1;
  t[pos].s[0] = build(l, mid);
  t[pos].s[1] = build(mid + 1, r);
  push_up(pos);
  return pos;
}
int find(int l, int r, int pos, int x, int kd) {
  if (l >= x) {
    if (kd)
      return t[pos].od;
    else
      return t[pos].ev;
  }
  if (r < x)
    return -1e9;
  int mid = (l + r) >> 1;
  int ret = find(l, mid, t[pos].s[0], x, kd);
  ret = max(ret, find(mid + 1, r, t[pos].s[1], x, kd));
  return ret;
}
int modify(int l, int r, int pos, int tar, int v1, int v2) {
  int cur = ++tcnt;
  if (l == r) {
    t[cur].ev = v1;
    t[cur].od = v2;
    return cur;
  }
  int mid = (l + r) >> 1;
  if (tar <= mid) {
    t[cur].s[0] = modify(l, mid, t[pos].s[0], tar, v1, v2);
    t[cur].s[1] = t[pos].s[1];
  } else {
    t[cur].s[0] = t[pos].s[0];
    t[cur].s[1] = modify(mid + 1, r, t[pos].s[1], tar, v1, v2);
  }
  push_up(cur);
  return cur;
}
bool chk(int h1, int c1, int h2, int c2, int len) {
  int t = c1 - c2 + suf[len + 1];
  if (t >= 0) {
    int res = find(1, n + 1, rt[len + 1], h2 + 1, t & 1);
    ;
    return res >= t;
  } else
    return false;
}
void preproc() {
  rt[n + 1] = build(1, n + 1);
  for (int i = n; i >= 1; --i) {
    int ev = find(1, n + 1, rt[i + 1], a[i] + 1, 0);
    int od = find(1, n + 1, rt[i + 1], a[i] + 1, 1);
    ev += 1 + mark[i];
    od += 1 + mark[i];
    if (ev & 1)
      swap(ev, od);
    rt[i] = modify(1, n + 1, rt[i + 1], a[i], ev, od);
  }
}
int main() {
  // open();
  n = read();
  int pre = -1;
  for (int i = 1; i <= n; ++i) {
    a[i] = read();
    if (a[i] > pre) {
      pre = a[i];
      mark[i] = 1;
    }
  }
  for (int i = n; i >= 1; --i) {
    if (mark[i])
      suf[i] = suf[i + 1] + 1;
    else
      suf[i] = suf[i + 1];
  }
  preproc();
  int pre1 = -1, pre2 = -1;
  int pc1 = 0, pc2 = 0;
  bool fail = 0;
  for (int i = 1; i <= n; ++i) {
    op[i] = 0;
    int h1 = pre1, h2 = pre2, cnt1 = pc1, cnt2 = pc2;
    if (a[i] > pre1) {
      h1 = a[i];
      ++cnt1;
    }
    if (chk(h1, cnt1, h2, cnt2, i) || chk(h2, cnt2, h1, cnt1, i)) {
      pre1 = h1, pre2 = h2, pc1 = cnt1, pc2 = cnt2;
      continue;
    }
    op[i] = 1;
    h1 = pre1, h2 = pre2, cnt1 = pc1, cnt2 = pc2;
    if (a[i] > pre2) {
      h2 = a[i];
      ++cnt2;
    }
    if (chk(h1, cnt1, h2, cnt2, i) || chk(h2, cnt2, h1, cnt1, i)) {
      pre1 = h1, pre2 = h2, pc1 = cnt1, pc2 = cnt2;
      continue;
    }
    fail = 1;
    break;
  }
  if (fail) {
    printf("-1\n");
  } else {
    for (int i = 1; i <= n; ++i) {
      putchar('0' + op[i]);
    }
    putchar('\n');
  }
  close();
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
#define LL long long
#define LD long double
using namespace std;
const int NN = 200000 + 117;
const int MM = 200000 + 117;
int read() {
  int fl = 1, x;
  char c;
  for (c = getchar(); (c < '0' || c > '9') && c != '-'; c = getchar())
    ;
  if (c == '-') {
    fl = -1;
    c = getchar();
  }
  for (x = 0; c >= '0' && c <= '9'; c = getchar())
    x = (x << 3) + (x << 1) + c - '0';
  return x * fl;
}
void open() {
  freopen("a.in", "r", stdin);
  // freopen("a.out","w",stdout);
}
void close() {
  fclose(stdin);
  fclose(stdout);
}

int m, n;
bool mark[NN] = {};
int suf[NN] = {};
struct seg {
  int ev, od;
  int s[2];
} t[30 * NN] = {};
int tcnt = 0;
int a[NN] = {};
int rt[NN] = {};
int op[NN] = {};
void push_up(int pos) {
  int ls = t[pos].s[0];
  int rs = t[pos].s[1];
  t[pos].ev = max(t[ls].ev, t[rs].ev);
  t[pos].od = max(t[ls].od, t[rs].od);
}
int build(int l, int r) {
  int pos = ++tcnt;
  if (l == r) {
    t[pos].ev = 0;
    t[pos].od = -1e9 + 1;
    return pos;
  }
  int mid = (l + r) >> 1;
  t[pos].s[0] = build(l, mid);
  t[pos].s[1] = build(mid + 1, r);
  push_up(pos);
  return pos;
}
int find(int l, int r, int pos, int x, int kd) {
  if (l >= x) {
    if (kd)
      return t[pos].od;
    else
      return t[pos].ev;
  }
  if (r < x)
    return -1e9;
  int mid = (l + r) >> 1;
  int ret = find(l, mid, t[pos].s[0], x, kd);
  ret = max(ret, find(mid + 1, r, t[pos].s[1], x, kd));
  return ret;
}
int modify(int l, int r, int pos, int tar, int v1, int v2) {
  int cur = ++tcnt;
  if (l == r) {
    t[cur].ev = v1;
    t[cur].od = v2;
    return cur;
  }
  int mid = (l + r) >> 1;
  if (tar <= mid) {
    t[cur].s[0] = modify(l, mid, t[pos].s[0], tar, v1, v2);
    t[cur].s[1] = t[pos].s[1];
  } else {
    t[cur].s[0] = t[pos].s[0];
    t[cur].s[1] = modify(mid + 1, r, t[pos].s[1], tar, v1, v2);
  }
  push_up(cur);
  return cur;
}
bool chk(int h1, int c1, int h2, int c2, int len) {
  int t = c1 - c2 + suf[len + 1];
  if (t >= 0) {
    int res = find(1, n + 1, rt[len + 1], h2 + 1, t & 1);
    ;
    return res >= t;
  } else
    return false;
}
void preproc() {
  rt[n + 1] = build(1, n + 1);
  for (int i = n; i >= 1; --i) {
    int ev = find(1, n + 1, rt[i + 1], a[i] + 1, 0);
    int od = find(1, n + 1, rt[i + 1], a[i] + 1, 1);
    ev += 1 + mark[i];
    od += 1 + mark[i];
    if (ev & 1)
      swap(ev, od);
    rt[i] = modify(1, n + 1, rt[i + 1], a[i], ev, od);
  }
}
int main() {
  // open();
  n = read();
  int pre = -1;
  for (int i = 1; i <= n; ++i) {
    a[i] = read();
    if (a[i] > pre) {
      pre = a[i];
      mark[i] = 1;
    }
  }
  for (int i = n; i >= 1; --i) {
    if (mark[i])
      suf[i] = suf[i + 1] + 1;
    else
      suf[i] = suf[i + 1];
  }
  preproc();
  int pre1 = -1, pre2 = -1;
  int pc1 = 0, pc2 = 0;
  bool fail = 0;
  for (int i = 1; i <= n; ++i) {
    op[i] = 0;
    int h1 = pre1, h2 = pre2, cnt1 = pc1, cnt2 = pc2;
    if (a[i] > pre1) {
      h1 = a[i];
      ++cnt1;
    }
    if (chk(h1, cnt1, h2, cnt2, i) || chk(h2, cnt2, h1, cnt1, i)) {
      pre1 = h1, pre2 = h2, pc1 = cnt1, pc2 = cnt2;
      continue;
    }
    op[i] = 1;
    h1 = pre1, h2 = pre2, cnt1 = pc1, cnt2 = pc2;
    if (a[i] > pre2) {
      h2 = a[i];
      ++cnt2;
    }
    if (chk(h1, cnt1, h2, cnt2, i) || chk(h2, cnt2, h1, cnt1, i)) {
      pre1 = h1, pre2 = h2, pc1 = cnt1, pc2 = cnt2;
      continue;
    }
    fail = 1;
    break;
  }
  if (fail) {
    printf("-1\n");
  } else {
    for (int i = 1; i <= n; ++i) {
      putchar('0' + op[i]);
    }
    putchar('\n');
  }
  close();
  return 0;
}