Problem p03235 (C++)

Buggy submission (status: Runtime Error):
#ifndef BZ
#pragma GCC optimize "Ofast"
#endif
#include <bits/stdc++.h>
using namespace std;
using ull = uint64_t;
using ll = int64_t;
using ld = long double;

const int MAXN = 200228;
int a[MAXN];
bool must[MAXN];
int mustcnt[MAXN];

int bef[MAXN][2];

int n;
int fn;

struct Fen {

  Fen() { fill(begin(fen), end(fen), -MAXN); }

  int fen[MAXN];

  vector<pair<int, int>> changes;

  void upd(int x, int y) {
    for (int i = x; i <= fn + 1; i |= (i + 1)) {
      changes.emplace_back(i, fen[i]);
      fen[i] = max(fen[i], y);
    }
  }

  int gt(int x) {
    int ans = -MAXN;
    for (int i = x + 1; --i >= 0; i &= (i + 1)) {
      ans = max(ans, fen[i]);
    }

    return ans;
  }

  void pop(int sz) {
    while (changes.size() > sz) {
      fen[changes.back().first] = changes.back().second;
      changes.pop_back();
    }
  }
};

Fen fens[2];

bool good(int id, int x, int y, int d) {
  if (fens[0].gt(x) + d - mustcnt[id] < 0 ||
      fens[0].gt(y) - d - mustcnt[id] < 0) {
    return false;
  }

  if (mustcnt[id] == d % 2) {
    return true;
  }

  return fens[1].gt(x) + d - mustcnt[id] >= 0 ||
         fens[1].gt(y) - d - mustcnt[id] >= 0;
}

int main() {
#ifdef BZ
  freopen("input.txt", "r", stdin);
#endif
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  cout.setf(ios::fixed);
  cout.precision(20);
  cin >> n;
  fn = n + 2;
  int cm = n + 2;
  for (int i = 0; i < n; ++i) {
    cin >> a[i];
    a[i] = n + 1 - a[i];
    must[i] = a[i] < cm;
    cm = min(cm, a[i]);
  }

  fens[0].upd(0, 0);

  for (int i = n - 1; i >= 0; --i) {
    mustcnt[i] = mustcnt[i + 1] + must[i];
    for (int j = 0; j < 2; ++j) {
      bef[i][j] = fens[j].changes.size();
    }

    for (int j = 0; j < 2; ++j) {
      for (int k = j; k < 2; ++k) {
        int cur = fens[j].gt(a[i] - 1);
        ++cur;
        cur += must[i];
        if (must[i] && k > j) {
          continue;
        }

        fens[k].upd(a[i], cur);
      }
    }
  }

  if (!good(0, n, n, 0)) {
    cout << "-1\n";
    return 0;
  }

  int x = fn + 2, y = fn + 2, d = 0;

  for (int i = 0; i < n; ++i) {
    int id = i + 1;

    for (int j = 0; j < 2; ++j) {
      fens[j].pop(bef[i][j]);
    }

    {
      int nx = x, ny = y, nd = d;
      if (a[i] < nx) {
        nx = a[i];
        ++nd;
      }

      if (good(id, nx, ny, nd)) {
        cout << 0;
        x = nx;
        y = ny;
        d = nd;
        continue;
      }
    }

    {
      int nx = x, ny = y, nd = d;
      if (a[i] < ny) {
        ny = a[i];
        --nd;
      }

      if (good(id, nx, ny, nd)) {
        cout << 1;
        x = nx;
        y = ny;
        d = nd;
        continue;
      }
    }

    assert(false);
  }

  assert(d == 0);

  cout << "\n";
}


Fixed submission:
#ifndef BZ
#pragma GCC optimize "Ofast"
#endif
#include <bits/stdc++.h>
using namespace std;
using ull = uint64_t;
using ll = int64_t;
using ld = long double;

const int MAXN = 200228;
int a[MAXN];
bool must[MAXN];
int mustcnt[MAXN];

int bef[MAXN][2];

int n;
int fn;

struct Fen {

  Fen() { fill(begin(fen), end(fen), -MAXN); }

  int fen[MAXN];

  vector<pair<int, int>> changes;

  void upd(int x, int y) {
    for (int i = x; i <= fn + 1; i |= (i + 1)) {
      changes.emplace_back(i, fen[i]);
      fen[i] = max(fen[i], y);
    }
  }

  int gt(int x) {
    int ans = -MAXN;
    for (int i = x + 1; --i >= 0; i &= (i + 1)) {
      ans = max(ans, fen[i]);
    }

    return ans;
  }

  void pop(int sz) {
    while (changes.size() > sz) {
      fen[changes.back().first] = changes.back().second;
      changes.pop_back();
    }
  }
};

Fen fens[2];

bool good(int id, int x, int y, int d) {
  if (fens[0].gt(x) + d - mustcnt[id] < 0 ||
      fens[0].gt(y) - d - mustcnt[id] < 0) {
    return false;
  }

  if (mustcnt[id] % 2 == d % 2) {
    return true;
  }

  return fens[1].gt(x) + d - mustcnt[id] >= 0 ||
         fens[1].gt(y) - d - mustcnt[id] >= 0;
}

int main() {
#ifdef BZ
  freopen("input.txt", "r", stdin);
#endif
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  cout.setf(ios::fixed);
  cout.precision(20);
  cin >> n;
  fn = n + 2;
  int cm = n + 2;
  for (int i = 0; i < n; ++i) {
    cin >> a[i];
    a[i] = n + 1 - a[i];
    must[i] = a[i] < cm;
    cm = min(cm, a[i]);
  }

  fens[0].upd(0, 0);

  for (int i = n - 1; i >= 0; --i) {
    mustcnt[i] = mustcnt[i + 1] + must[i];
    for (int j = 0; j < 2; ++j) {
      bef[i][j] = fens[j].changes.size();
    }

    for (int j = 0; j < 2; ++j) {
      for (int k = j; k < 2; ++k) {
        int cur = fens[j].gt(a[i] - 1);
        ++cur;
        cur += must[i];
        if (must[i] && k > j) {
          continue;
        }

        fens[k].upd(a[i], cur);
      }
    }
  }

  if (!good(0, n, n, 0)) {
    cout << "-1\n";
    return 0;
  }

  int x = fn + 2, y = fn + 2, d = 0;

  for (int i = 0; i < n; ++i) {
    int id = i + 1;

    for (int j = 0; j < 2; ++j) {
      fens[j].pop(bef[i][j]);
    }

    {
      int nx = x, ny = y, nd = d;
      if (a[i] < nx) {
        nx = a[i];
        ++nd;
      }

      if (good(id, nx, ny, nd)) {
        cout << 0;
        x = nx;
        y = ny;
        d = nd;
        continue;
      }
    }

    {
      int nx = x, ny = y, nd = d;
      if (a[i] < ny) {
        ny = a[i];
        --nd;
      }

      if (good(id, nx, ny, nd)) {
        cout << 1;
        x = nx;
        y = ny;
        d = nd;
        continue;
      }
    }

    assert(false);
  }

  assert(d == 0);

  cout << "\n";
}