Problem p03554 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

using namespace std;

using i64 = int64_t;

const i64 MOD = 1e9 + 7;

const i64 INF = 1e18 + 7;

template <typename T> struct Segtree {
  int n;
  T op;
  vector<T> elm;
  function<T(T, T)> f;

  Segtree(int n, vector<T> init, function<T(T, T)> f, T op = T())
      : n(n), op(op), elm(2 * n), f(f) {
    for (int i = 0; i < n; ++i)
      elm[i + n] = init[i];
    for (int i = n - 1; i > 0; --i)
      elm[i] = f(elm[2 * i], elm[2 * i + 1]);
  }

  void set(int x, T val) {
    x += n;
    elm[x] = val;
    while (x >>= 1)
      elm[x] = f(elm[2 * x], elm[2 * x + 1]);
  }

  void update(int x, T val) {
    x += n;
    elm[x] = f(val, elm[x]);
    while (x >>= 1)
      elm[x] = f(elm[2 * x], elm[2 * x + 1]);
  }

  T get(int x, int y) const {
    T val = op;
    for (x += n, y += n - 1; x <= y; x >>= 1, y >>= 1) {
      if (x & 1)
        val = f(val, elm[x++]);
      if (!(y & 1))
        val = f(val, elm[y--]);
    }
    return val;
  }
};

template <typename T, typename U> struct LazySegtree {
  const int n;
  const T op_t;
  const U op_u;
  vector<T> elm;
  vector<U> lazy;
  vector<int> length;
  function<T(T, T)> f;
  function<T(T, U, int)> g;
  function<U(U, U)> h;

  LazySegtree(int n, T init, function<T(T, T)> f, function<T(T, U, int)> g,
              function<U(U, U)> h, T op_t = T(), U op_u = U())
      : n(n), op_t(op_t), op_u(op_u), elm(2 * n, init), lazy(2 * n, op_u),
        length(2 * n, 0), f(f), g(g), h(h) {
    for (int i = n - 1; i > 0; --i) {
      elm[i] = f(elm[2 * i], elm[2 * i + 1]);
      length[i] = length[2 * i] + 1;
    }
  }

  vector<int> get_list(int x, int y) {

    vector<int> ret_list;
    for (x += n, y += n - 1; x; x >>= 1, y >>= 1) {
      ret_list.emplace_back(x);
      if (x != y)
        ret_list.emplace_back(y);
    }

    return ret_list;
  }

  void eval(int x) {

    elm[x] = g(elm[x], lazy[x], 1 << length[x]);
    if (x < n) {
      lazy[2 * x] = h(lazy[2 * x], lazy[x]);
      lazy[2 * x + 1] = h(lazy[2 * x + 1], lazy[x]);
    }
    lazy[x] = op_u;
  }

  void update(int x, int y, U val) {

    vector<int> index_list = get_list(x, y);
    for (int i = index_list.size() - 1; i >= 0; --i)
      eval(index_list[i]);

    for (x += n, y += n - 1; x <= y; x >>= 1, y >>= 1) {
      if (x & 1) {
        lazy[x] = h(lazy[x], val);
        eval(x++);
      }
      if (!(y & 1)) {
        lazy[y] = h(lazy[y], val);
        eval(y--);
      }
    }

    for (auto index : index_list) {
      if (index < n) {
        eval(2 * index);
        eval(2 * index + 1);
        elm[index] = f(elm[2 * index], elm[2 * index + 1]);
      }
    }
  }

  T get(int x, int y) {

    vector<int> index_list = get_list(x, y);
    for (int i = index_list.size() - 1; i >= 0; --i)
      eval(index_list[i]);

    T val = op_t;
    for (x += n, y += n - 1; x <= y; x >>= 1, y >>= 1) {
      if (x & 1) {
        eval(x);
        val = f(val, elm[x++]);
      }
      if (!(y & 1)) {
        eval(y);
        val = f(val, elm[y--]);
      }
    }
    return val;
  }
};

signed main() {
  i64 n;
  cin >> n;
  vector<i64> a(n);
  for (auto &x : a)
    cin >> x;
  i64 q;
  cin >> q;
  vector<i64> l(q), r(q);
  vector<pair<i64, i64>> p(q);
  for (i64 i = 0; i < q; ++i) {
    cin >> l[i] >> r[i];
    p[i] = make_pair(--l[i], r[i]);
  }

  sort(p.begin(), p.end());
  i64 before = 0;
  vector<i64> b(1, 0);
  for (i64 i = 0; i < n; ++i)
    b.emplace_back(b.back() + a[i]);

  // [ll, rr)のpopcount
  auto c1 = [&](i64 ll, i64 rr) {
    assert(ll >= 0 && rr <= n);
    return b[rr] - b[ll];
  };
  auto c0 = [&](i64 ll, i64 rr) { return (rr - ll) - c1(ll, rr); };

  // dp[i]: [0, i)地点で一致しているものの数
  vector<i64> dp(n + 1, -INF);

  dp[0] = 0;

  map<int, vector<int>> m;
  for (int i = 0; i < n; ++i)
    m[p[i].first].emplace_back(p[i].second);

  vector<i64> dp2_tmp(n + 1);
  for (int i = 0; i <= n; ++i)
    dp2_tmp[i] = c1(i, n);

  auto dp2_ori = dp2_tmp;
  for (int i = 1; i <= n; ++i)
    dp2_ori[i] -= INF;

  // 区間加算のSegtree
  LazySegtree<i64, i64> dp1(
      n + 1, 0, [](i64 x, i64 y) { return max(x, y); },
      [](i64 x, i64 y, int z) { return x + y; },
      [](i64 x, i64 y) { return x + y; }, -INF, 0);
  dp1.update(1, n + 1, -INF);
  // 初期値でアレを保持するSegtree
  Segtree<i64> dp2(
      n + 1, dp2_ori, [](i64 x, i64 y) { return max(x, y); }, -INF);

  for (int i = 0; i <= n; ++i) {
    if (i)
      dp1.update(0, i, !a[i - 1]);

    for (auto &j : m[i]) {
      i64 before = dp[j];

      dp[j] = max(dp[j], dp1.get(0, i) + c1(i, j));
      dp[j] = max(dp[j], dp2.get(i, j) - c1(j, n));

      i64 after = dp[j];

      i64 diff = after - before;
      dp1.update(j, j + 1, diff);
      dp2.set(j, after + dp2_tmp[j]);
    }
  }

  i64 ans = INF;
  for (i64 i = 0; i <= n; ++i) {
    ans = min(ans, n - (dp[i] + c0(i, n)));
  }

  cout << ans << endl;
}


Fixed submission:
#include <bits/stdc++.h>

using namespace std;

using i64 = int64_t;

const i64 MOD = 1e9 + 7;

const i64 INF = 1e18 + 7;

template <typename T> struct Segtree {
  int n;
  T op;
  vector<T> elm;
  function<T(T, T)> f;

  Segtree(int n, vector<T> init, function<T(T, T)> f, T op = T())
      : n(n), op(op), elm(2 * n), f(f) {
    for (int i = 0; i < n; ++i)
      elm[i + n] = init[i];
    for (int i = n - 1; i > 0; --i)
      elm[i] = f(elm[2 * i], elm[2 * i + 1]);
  }

  void set(int x, T val) {
    x += n;
    elm[x] = val;
    while (x >>= 1)
      elm[x] = f(elm[2 * x], elm[2 * x + 1]);
  }

  void update(int x, T val) {
    x += n;
    elm[x] = f(val, elm[x]);
    while (x >>= 1)
      elm[x] = f(elm[2 * x], elm[2 * x + 1]);
  }

  T get(int x, int y) const {
    T val = op;
    for (x += n, y += n - 1; x <= y; x >>= 1, y >>= 1) {
      if (x & 1)
        val = f(val, elm[x++]);
      if (!(y & 1))
        val = f(val, elm[y--]);
    }
    return val;
  }
};

template <typename T, typename U> struct LazySegtree {
  const int n;
  const T op_t;
  const U op_u;
  vector<T> elm;
  vector<U> lazy;
  vector<int> length;
  function<T(T, T)> f;
  function<T(T, U, int)> g;
  function<U(U, U)> h;

  LazySegtree(int n, T init, function<T(T, T)> f, function<T(T, U, int)> g,
              function<U(U, U)> h, T op_t = T(), U op_u = U())
      : n(n), op_t(op_t), op_u(op_u), elm(2 * n, init), lazy(2 * n, op_u),
        length(2 * n, 0), f(f), g(g), h(h) {
    for (int i = n - 1; i > 0; --i) {
      elm[i] = f(elm[2 * i], elm[2 * i + 1]);
      length[i] = length[2 * i] + 1;
    }
  }

  vector<int> get_list(int x, int y) {

    vector<int> ret_list;
    for (x += n, y += n - 1; x; x >>= 1, y >>= 1) {
      ret_list.emplace_back(x);
      if (x != y)
        ret_list.emplace_back(y);
    }

    return ret_list;
  }

  void eval(int x) {

    elm[x] = g(elm[x], lazy[x], 1 << length[x]);
    if (x < n) {
      lazy[2 * x] = h(lazy[2 * x], lazy[x]);
      lazy[2 * x + 1] = h(lazy[2 * x + 1], lazy[x]);
    }
    lazy[x] = op_u;
  }

  void update(int x, int y, U val) {

    vector<int> index_list = get_list(x, y);
    for (int i = index_list.size() - 1; i >= 0; --i)
      eval(index_list[i]);

    for (x += n, y += n - 1; x <= y; x >>= 1, y >>= 1) {
      if (x & 1) {
        lazy[x] = h(lazy[x], val);
        eval(x++);
      }
      if (!(y & 1)) {
        lazy[y] = h(lazy[y], val);
        eval(y--);
      }
    }

    for (auto index : index_list) {
      if (index < n) {
        eval(2 * index);
        eval(2 * index + 1);
        elm[index] = f(elm[2 * index], elm[2 * index + 1]);
      }
    }
  }

  T get(int x, int y) {

    vector<int> index_list = get_list(x, y);
    for (int i = index_list.size() - 1; i >= 0; --i)
      eval(index_list[i]);

    T val = op_t;
    for (x += n, y += n - 1; x <= y; x >>= 1, y >>= 1) {
      if (x & 1) {
        eval(x);
        val = f(val, elm[x++]);
      }
      if (!(y & 1)) {
        eval(y);
        val = f(val, elm[y--]);
      }
    }
    return val;
  }
};

signed main() {
  i64 n;
  cin >> n;
  vector<i64> a(n);
  for (auto &x : a)
    cin >> x;
  i64 q;
  cin >> q;
  vector<i64> l(q), r(q);
  vector<pair<i64, i64>> p(q);
  for (i64 i = 0; i < q; ++i) {
    cin >> l[i] >> r[i];
    p[i] = make_pair(--l[i], r[i]);
  }

  sort(p.begin(), p.end());
  i64 before = 0;
  vector<i64> b(1, 0);
  for (i64 i = 0; i < n; ++i)
    b.emplace_back(b.back() + a[i]);

  // [ll, rr)のpopcount
  auto c1 = [&](i64 ll, i64 rr) {
    assert(ll >= 0 && rr <= n);
    return b[rr] - b[ll];
  };
  auto c0 = [&](i64 ll, i64 rr) { return (rr - ll) - c1(ll, rr); };

  // dp[i]: [0, i)地点で一致しているものの数
  vector<i64> dp(n + 1, -INF);

  dp[0] = 0;

  map<int, vector<int>> m;
  for (int i = 0; i < q; ++i)
    m[p[i].first].emplace_back(p[i].second);

  vector<i64> dp2_tmp(n + 1);
  for (int i = 0; i <= n; ++i)
    dp2_tmp[i] = c1(i, n);

  auto dp2_ori = dp2_tmp;
  for (int i = 1; i <= n; ++i)
    dp2_ori[i] -= INF;

  // 区間加算のSegtree
  LazySegtree<i64, i64> dp1(
      n + 1, 0, [](i64 x, i64 y) { return max(x, y); },
      [](i64 x, i64 y, int z) { return x + y; },
      [](i64 x, i64 y) { return x + y; }, -INF, 0);
  dp1.update(1, n + 1, -INF);
  // 初期値でアレを保持するSegtree
  Segtree<i64> dp2(
      n + 1, dp2_ori, [](i64 x, i64 y) { return max(x, y); }, -INF);

  for (int i = 0; i <= n; ++i) {
    if (i)
      dp1.update(0, i, !a[i - 1]);

    for (auto &j : m[i]) {
      i64 before = dp[j];

      dp[j] = max(dp[j], dp1.get(0, i) + c1(i, j));
      dp[j] = max(dp[j], dp2.get(i, j) - c1(j, n));

      i64 after = dp[j];

      i64 diff = after - before;
      dp1.update(j, j + 1, diff);
      dp2.set(j, after + dp2_tmp[j]);
    }
  }

  i64 ans = INF;
  for (i64 i = 0; i <= n; ++i) {
    ans = min(ans, n - (dp[i] + c0(i, n)));
  }

  cout << ans << endl;
}