Problem p03554 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

#define ll long long
#define ull unsigned long long
#define db long double
#define pb push_back
#define ppb pop_back
#define F first
#define S second
#define mp make_pair
#define all(x) (x).begin(), (x).end()

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vll;

typedef tree<pii, null_type, less<pii>, rb_tree_tag,
             tree_order_statistics_node_update>
    ordered_set;

const int N = 200003, K = 999;
int n, a[N], q, ind[N], dp[N], f[N];
pii query[N], p[N];
vi vec[N];

struct block {
  vector<pii> v, tmp_v;
  vi s, ord, tmp;
  int suf = N, val = -1;
  void add(int x) {
    for (int i = suf; i < (int)v.size(); i++) {
      v[i].F = val;
    }
    suf = N, val = -1;
    int l = p[x].F, r = p[x].S;
    v.pb({r, l});
    s.pb(dp[l - 1] - f[l - 1]);
    for (int i = (int)s.size() - 2; i >= 0; i--) {
      s[i] = min(s[i], s[i + 1]);
    }
  }
  int get(int x) {
    if (v.empty()) {
      return N;
    }
    int L = p[x].F, R = p[x].S;
    int pos = lower_bound(all(v), mp(L - 1, 0)) - v.begin();
    if (pos < suf) {
      if (pos == (int)v.size()) {
        return N;
      }
      suf = pos, val = R;
      return s[pos];
    } else {
      if (val >= L - 1) {
        val = R;
        return s[suf];
      } else {
        return N;
      }
    }
  }
  int naive_get(int x) {
    if (v.empty()) {
      return N;
    }
    int L = p[x].F, R = p[x].S, res = N;
    for (int i = 0; i < (int)v.size(); i++) {
      if (i >= suf) {
        v[i].F = val;
      }
      if (v[i].S <= L && v[i].F >= L - 1) {
        res = min(res, dp[v[i].S - 1] - f[v[i].S - 1]);
        v[i].F = R;
        tmp.pb(i);
      } else {
        ord.pb(i);
      }
    }
    suf = N, val = -1;
    for (int i = 0; i < (int)ord.size(); i++) {
      tmp_v.pb(v[ord[i]]);
    }
    for (int i = 0; i < (int)tmp.size(); i++) {
      tmp_v.pb(v[tmp[i]]);
    }
    v = tmp_v;
    ord.clear();
    tmp.clear();
    tmp_v.clear();
    for (int i = (int)s.size() - 1; i >= 0; i--) {
      if (i == (int)s.size() - 1) {
        s[i] = dp[v[i].S - 1] - f[v[i].S - 1];
      } else {
        s[i] = min(s[i + 1], dp[v[i].S - 1] - f[v[i].S - 1]);
      }
    }
    return res;
  }
};

block b[N / K];

int main() {
  ios_base::sync_with_stdio(false), cin.tie(NULL);
#ifdef LOCAL
  freopen("input.txt", "r", stdin);
#endif

  cin >> n;
  int s = 0;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
    f[i] = f[i - 1] + (a[i] == 0) - (a[i] == 1);
    s += a[i];
  }
  cin >> q;
  for (int i = 1; i <= q; i++) {
    int l, r;
    cin >> l >> r;
    p[i] = {l, r};
    vec[r].pb(i);
    query[i - 1] = {l, i};
  }
  sort(query, query + q);
  for (int i = 0; i < q; i++) {
    ind[query[i].S] = i;
  }
  for (int i = 1; i <= n; i++) {
    int res = N;
    for (int j : vec[i]) {
      b[ind[j] / K].add(j);
      for (int k = 0; k <= (q - 1) / K; k++) {
        int last = min(q - 1, K * (k + 1) - 1);
        if (query[last].F <= p[j].F && last < q - 1) {
          res = min(res, b[k].get(j));
        } else {
          res = min(res, b[k].naive_get(j));
          break;
        }
      }
    }
    dp[i] = min(dp[i - 1], res + f[i]);
  }
  cout << dp[n] + s;
}


Fixed submission:
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

#define ll long long
#define ull unsigned long long
#define db long double
#define pb push_back
#define ppb pop_back
#define F first
#define S second
#define mp make_pair
#define all(x) (x).begin(), (x).end()

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vll;

typedef tree<pii, null_type, less<pii>, rb_tree_tag,
             tree_order_statistics_node_update>
    ordered_set;

const int N = 200003, K = 999;
int n, a[N], q, ind[N], dp[N], f[N];
pii query[N], p[N];
vi vec[N];

struct block {
  vector<pii> v, tmp_v;
  vi s, ord, tmp;
  int suf = N, val = -1;
  void add(int x) {
    for (int i = suf; i < (int)v.size(); i++) {
      v[i].F = val;
    }
    suf = N, val = -1;
    int l = p[x].F, r = p[x].S;
    v.pb({r, l});
    s.pb(dp[l - 1] - f[l - 1]);
    for (int i = (int)s.size() - 2; i >= 0; i--) {
      s[i] = min(s[i], s[i + 1]);
    }
  }
  int get(int x) {
    if (v.empty()) {
      return N;
    }
    int L = p[x].F, R = p[x].S;
    int pos = lower_bound(all(v), mp(L - 1, 0)) - v.begin();
    if (pos < suf) {
      if (pos == (int)v.size()) {
        return N;
      }
      suf = pos, val = R;
      return s[pos];
    } else {
      if (val >= L - 1) {
        val = R;
        return s[suf];
      } else {
        return N;
      }
    }
  }
  int naive_get(int x) {
    if (v.empty()) {
      return N;
    }
    int L = p[x].F, R = p[x].S, res = N;
    for (int i = 0; i < (int)v.size(); i++) {
      if (i >= suf) {
        v[i].F = val;
      }
      if (v[i].S <= L && v[i].F >= L - 1) {
        res = min(res, dp[v[i].S - 1] - f[v[i].S - 1]);
        v[i].F = R;
        tmp.pb(i);
      } else {
        ord.pb(i);
      }
    }
    suf = N, val = -1;
    for (int i = 0; i < (int)ord.size(); i++) {
      tmp_v.pb(v[ord[i]]);
    }
    for (int i = 0; i < (int)tmp.size(); i++) {
      tmp_v.pb(v[tmp[i]]);
    }
    v = tmp_v;
    ord.clear();
    tmp.clear();
    tmp_v.clear();
    for (int i = (int)s.size() - 1; i >= 0; i--) {
      if (i == (int)s.size() - 1) {
        s[i] = dp[v[i].S - 1] - f[v[i].S - 1];
      } else {
        s[i] = min(s[i + 1], dp[v[i].S - 1] - f[v[i].S - 1]);
      }
    }
    return res;
  }
};

block b[N / K + 1];

int main() {
  ios_base::sync_with_stdio(false), cin.tie(NULL);
#ifdef LOCAL
  freopen("input.txt", "r", stdin);
#endif

  cin >> n;
  int s = 0;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
    f[i] = f[i - 1] + (a[i] == 0) - (a[i] == 1);
    s += a[i];
  }
  cin >> q;
  for (int i = 1; i <= q; i++) {
    int l, r;
    cin >> l >> r;
    p[i] = {l, r};
    vec[r].pb(i);
    query[i - 1] = {l, i};
  }
  sort(query, query + q);
  for (int i = 0; i < q; i++) {
    ind[query[i].S] = i;
  }
  for (int i = 1; i <= n; i++) {
    int res = N;
    for (int j : vec[i]) {
      b[ind[j] / K].add(j);
      for (int k = 0; k <= (q - 1) / K; k++) {
        int last = min(q - 1, K * (k + 1) - 1);
        if (query[last].F <= p[j].F && last < q - 1) {
          res = min(res, b[k].get(j));
        } else {
          res = min(res, b[k].naive_get(j));
          break;
        }
      }
    }
    dp[i] = min(dp[i - 1], res + f[i]);
  }
  cout << dp[n] + s;
}