Problem p02551 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

const i64 MOD = 1e9 + 7;
const i64 INF = i64(1e18) + 7;

template <typename T> bool chmin(T &x, T y) {
  if (x > y) {
    x = y;
    return true;
  }
  return false;
}

template <typename T> bool chmax(T &x, T y) {
  if (x < y) {
    x = y;
    return true;
  }
  return false;
}

class SegtreeBeats {
  using ll = long long;

  int n, rr;
  vector<ll> mx_v, mn_v, smx_v, smn_v, lz_upd, lz_ad, sigm, len;
  vector<int> mx_c, mn_c;
  const ll mx = 1e18, mn = -1e18;

public:
  SegtreeBeats() {}
  SegtreeBeats(vector<ll> &v) { init(v); }
  void init(vector<ll> &v) {
    n = v.size();
    rr = 1;
    while (rr < n)
      rr *= 2;

    mx_v.assign(2 * rr - 1, mn);
    mn_v.assign(2 * rr - 1, mx);
    smx_v.assign(2 * rr - 1, mn);
    smn_v.assign(2 * rr - 1, mx);
    lz_upd.assign(2 * rr - 1, mx);
    lz_ad.assign(2 * rr - 1, 0);
    len.assign(2 * rr - 1, rr);
    sigm.assign(2 * rr - 1, 0);
    mx_c.assign(2 * rr - 1, 1);
    mn_c.assign(2 * rr - 1, 1);

    for (int i = 0; i < rr - 1; i++)
      len[i * 2 + 1] = len[i * 2 + 2] = len[i] >> 1;

    for (int i = 0; i < n; i++) {
      mx_v[i + rr - 1] = mn_v[i + rr - 1] = sigm[i + rr - 1] = v[i];
    }
    for (int i = rr - 2; i >= 0; i--) {
      proc(i);
    }
  }

  void chmin(int a, int b, ll x) { chmin(0, a, b, 0, rr, x); }
  void chmax(int a, int b, ll x) { chmax(0, a, b, 0, rr, x); }
  void update(int a, int b, ll x) { update(0, a, b, 0, rr, x); }
  void add(int a, int b, ll x) { add(0, a, b, 0, rr, x); }

  ll rangemin(int a, int b) { return rangemin(0, a, b, 0, rr); }
  ll rangemax(int a, int b) { return rangemax(0, a, b, 0, rr); }
  ll sum(int a, int b) { return sum(0, a, b, 0, rr); }

private:
  ll rangemin(int i, int a, int b, int l, int r) {
    if (r <= a || b <= l)
      return mx;
    if (a <= l && r <= b)
      return mn_v[i];
    eval(i);
    ll lv = rangemin(i * 2 + 1, a, b, l, (l + r) / 2);
    ll rv = rangemin(i * 2 + 2, a, b, (l + r) / 2, r);
    return min(lv, rv);
  }
  ll rangemax(int i, int a, int b, int l, int r) {
    if (r <= a || b <= l)
      return mn;
    if (a <= l && r <= b)
      return mx_v[i];
    eval(i);
    ll lv = rangemax(i * 2 + 1, a, b, l, (l + r) / 2);
    ll rv = rangemax(i * 2 + 2, a, b, (l + r) / 2, r);
    return max(lv, rv);
  }
  ll sum(int i, int a, int b, int l, int r) {
    if (r <= a || b <= l)
      return 0;
    if (a <= l && r <= b)
      return sigm[i];
    eval(i);
    ll lv = sum(i * 2 + 1, a, b, l, (l + r) / 2);
    ll rv = sum(i * 2 + 2, a, b, (l + r) / 2, r);
    return lv + rv;
  }

  void chmin(int i, int a, int b, int l, int r, ll x) {
    if (b <= l || r <= a || x >= mx_v[i])
      return;

    if (a <= l && r <= b && smx_v[i] < x) {
      in_chmin(i, x);
      return;
    } // ここの値を直す。だけ。

    eval(i); // 子供の値も正しくする
    chmin(i * 2 + 1, a, b, l, (l + r) / 2, x);
    chmin(i * 2 + 2, a, b, (l + r) / 2, r, x);
    proc(i);
  }
  void chmax(int i, int a, int b, int l, int r, ll x) {
    if (b <= l || r <= a || x <= mn_v[i])
      return;

    if (a <= l && r <= b && smn_v[i] > x) {
      in_chmax(i, x);
      return;
    } // ここの値を直す。だけ。

    eval(i); // 子供の値も正しくする
    chmax(i * 2 + 1, a, b, l, (l + r) / 2, x);
    chmax(i * 2 + 2, a, b, (l + r) / 2, r, x);
    proc(i);
  }
  void add(int i, int a, int b, int l, int r, ll x) {
    if (b <= l || r <= a)
      return;

    if (a <= l && r <= b) {
      in_add(i, x);
      return;
    } // ここの値を直す。だけ。

    eval(i); // 子供の値も正しくする
    add(i * 2 + 1, a, b, l, (l + r) / 2, x);
    add(i * 2 + 2, a, b, (l + r) / 2, r, x);
    proc(i);
  }
  void update(int i, int a, int b, int l, int r, ll x) {
    if (b <= l || r <= a)
      return;

    if (a <= l && r <= b) {
      in_update(i, x);
      return;
    } // ここの値を直す。だけ。

    eval(i); // 子供の値も正しくする
    update(i * 2 + 1, a, b, l, (l + r) / 2, x);
    update(i * 2 + 2, a, b, (l + r) / 2, r, x);
    proc(i);
  }

  void eval(int i) {
    // chmin, update, add
    // update->add 組み込む
    // add->chmin やるだけ
    // chmin->add

    if (lz_upd[i] != mx) {
      in_update(i * 2 + 1, lz_upd[i]);
      in_update(i * 2 + 2, lz_upd[i]);
      lz_upd[i] = mx;
      return;
    } // updateされていた場合は、死ぬ

    if (lz_ad[i]) {
      in_add(i * 2 + 1, lz_ad[i]);
      in_add(i * 2 + 2, lz_ad[i]);
      lz_ad[i] = 0;
    }

    if (mx_v[i] < mx_v[i * 2 + 1])
      in_chmin(i * 2 + 1, mx_v[i]);
    if (mx_v[i] < mx_v[i * 2 + 2])
      in_chmin(i * 2 + 2, mx_v[i]);

    if (mn_v[i] > mn_v[i * 2 + 1])
      in_chmax(i * 2 + 1, mn_v[i]);
    if (mn_v[i] > mn_v[i * 2 + 2])
      in_chmax(i * 2 + 2, mn_v[i]);
  } // 子供に情報を伝搬する

  void proc(int i) {
    sigm[i] = sigm[i * 2 + 1] + sigm[i * 2 + 2];

    mx_v[i] = max(mx_v[i * 2 + 1], mx_v[i * 2 + 2]);
    if (mx_v[i * 2 + 1] > mx_v[i * 2 + 2]) {
      mx_c[i] = mx_c[i * 2 + 1];
      smx_v[i] = max(smx_v[i * 2 + 1], mx_v[i * 2 + 2]);
    } else if (mx_v[i * 2 + 1] < mx_v[i * 2 + 2]) {
      mx_c[i] = mx_c[i * 2 + 2];
      smx_v[i] = max(smx_v[i * 2 + 2], mx_v[i * 2 + 1]);
    } else {
      mx_c[i] = mx_c[i * 2 + 1] + mx_c[i * 2 + 2];
      smx_v[i] = max(smx_v[i * 2 + 1], smx_v[i * 2 + 2]);
    }

    mn_v[i] = min(mn_v[i * 2 + 1], mn_v[i * 2 + 2]);
    if (mn_v[i * 2 + 1] < mn_v[i * 2 + 2]) {
      mn_c[i] = mn_c[i * 2 + 1];
      smn_v[i] = min(smn_v[i * 2 + 1], mn_v[i * 2 + 2]);
    } else if (mn_v[i * 2 + 1] > mn_v[i * 2 + 2]) {
      mn_c[i] = mn_c[i * 2 + 2];
      smn_v[i] = min(smn_v[i * 2 + 2], mn_v[i * 2 + 1]);
    } else {
      mn_c[i] = mn_c[i * 2 + 1] + mn_c[i * 2 + 2];
      smn_v[i] = min(smn_v[i * 2 + 1], smn_v[i * 2 + 2]);
    }
  } // 子供から値を伝搬する

  void in_update(int i, ll x) {
    mx_v[i] = mn_v[i] = x;
    smx_v[i] = mn;
    smn_v[i] = mx;
    mx_c[i] = mn_c[i] = len[i];
    sigm[i] = len[i] * x;
    lz_upd[i] = x, lz_ad[i] = 0;
  }
  void in_add(int i, ll x) {
    mx_v[i] += x;
    mn_v[i] += x;
    if (smn_v[i] != mx)
      smn_v[i] += x;
    if (smx_v[i] != mn)
      smx_v[i] += x;
    sigm[i] += x * len[i];

    if (lz_upd[i] != mx)
      lz_upd[i] += x;
    lz_ad[i] += x;
  }
  void in_chmin(int i, ll x) {
    sigm[i] += (x - mx_v[i]) * mx_c[i];

    if (mx_v[i] == mn_v[i])
      mx_v[i] = mn_v[i] = x;
    else if (mx_v[i] == smn_v[i])
      mx_v[i] = smn_v[i] = x;
    else
      mx_v[i] = x;

    if (lz_upd[i] != mx && lz_upd[i] > x)
      lz_upd[i] = x;
  }
  void in_chmax(int i, ll x) {
    sigm[i] += (x - mn_v[i]) * mn_c[i];

    if (mn_v[i] == mx_v[i])
      mx_v[i] = mn_v[i] = x;
    else if (mn_v[i] == smx_v[i])
      mn_v[i] = smx_v[i] = x;
    else
      mn_v[i] = x;

    if (lz_upd[i] != mx && lz_upd[i] < x)
      lz_upd[i] = x;
  }
};

signed main() {
  i64 n, q;
  cin >> n >> q;
  /*
  if(n == 3){
      if(q)
          cout << 0 << endl;
      else
          cout << 1 << endl;
      return 0;
  }
   */
  vector<i64> a1(n - 1, n - 2);
  SegtreeBeats seg1(a1);
  SegtreeBeats seg2(a1);
  i64 ans = (n - 2) * (n - 2);
  for (int i = 0; i < q; ++i) {
    int ty, x;
    cin >> ty >> x;
    x -= 2;
    if (ty == 1) {
      i64 v = seg1.rangemin(x, x + 1);
      ans -= v;
      seg2.chmin(0, v, x);
    } else {
      i64 v = seg2.rangemin(x, x + 1);
      ans -= v;
      seg1.chmin(0, v, x);
    }
  }
  cout << ans << endl;
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

const i64 MOD = 1e9 + 7;
const i64 INF = i64(1e18) + 7;

template <typename T> bool chmin(T &x, T y) {
  if (x > y) {
    x = y;
    return true;
  }
  return false;
}

template <typename T> bool chmax(T &x, T y) {
  if (x < y) {
    x = y;
    return true;
  }
  return false;
}

// doc:
// https://shibh308.github.io/library/library/lib/classes/lazysegtree.cpp.html
template <typename T, typename U> struct Segtree {
  int n;
  T op_t;
  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;

  Segtree(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;
    }
  }

  Segtree(int n, vector<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), lazy(2 * n, op_u),
        length(2 * n, 0), f(f), g(g), h(h) {
    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]);
      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) {

    if (x == y)
      return;
    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 l = op_t, r = op_t;
    for (x += n, y += n - 1; x <= y; x >>= 1, y >>= 1) {
      if (x & 1) {
        eval(x);
        l = f(l, elm[x++]);
      }
      if (!(y & 1)) {
        eval(y);
        r = f(elm[y--], r);
      }
    }
    return f(l, r);
  }
};

#define REP(i, n) for (int i = 0; (i) < (int)(n); ++(i))
#define REP3(i, m, n) for (int i = (m); (i) < (int)(n); ++(i))
#define REP_R(i, n) for (int i = (int)(n)-1; (i) >= 0; --(i))
#define REP3R(i, m, n) for (int i = (int)(n)-1; (i) >= (int)(m); --(i))
#define ALL(x) std::begin(x), std::end(x)

/**
 * @brief Segment Tree Beats (range {chmin, chmax, add, update} + range {min,
 * max, sum}, 完全二分木)
 * @docs data_structure/segment_tree_beats.md
 * @see https://codeforces.com/blog/entry/57319
 */
class segment_tree_beats {
  // MEMO: values for queries (max, min, lazy_add, and lazy_update) already
  // apply to the current node; but not for children
  typedef struct {
    int64_t max;
    int64_t max_second;
    int max_count;
    int64_t min;
    int64_t min_second;
    int min_count;
    int64_t lazy_add;
    int64_t lazy_update;
    int64_t sum;
  } value_type;

  int n;
  std::vector<value_type> a;

public:
  segment_tree_beats() = default;
  segment_tree_beats(int n_) {
    n = 1;
    while (n < n_)
      n *= 2;
    a.resize(2 * n + 5);
    tag<UPDATE>(0, 0);
  }
  template <class InputIterator>
  segment_tree_beats(InputIterator first, InputIterator last) {
    int n_ = std::distance(first, last);
    n = 1;
    while (n < n_)
      n *= 2;
    a.resize(2 * n - 1);
    REP(i, n_) { tag<UPDATE>(n - 1 + i, *(first + i)); }
    REP3(i, n_, n) { tag<UPDATE>(n - 1 + i, 0); }
    REP_R(i, n - 1) { update(i); }
  }

  void range_chmin(int l, int r, int64_t value) { // 0-based, [l, r)
    assert(0 <= l and l <= r and r <= n);
    range_apply<CHMIN>(0, 0, n, l, r, value);
  }
  void range_chmax(int l, int r, int64_t value) { // 0-based, [l, r)
    assert(0 <= l and l <= r and r <= n);
    range_apply<CHMAX>(0, 0, n, l, r, value);
  }
  void range_add(int l, int r, int64_t value) { // 0-based, [l, r)
    assert(0 <= l and l <= r and r <= n);
    range_apply<ADD>(0, 0, n, l, r, value);
  }
  void range_update(int l, int r, int64_t value) { // 0-based, [l, r)
    assert(0 <= l and l <= r and r <= n);
    range_apply<UPDATE>(0, 0, n, l, r, value);
  }

  int64_t range_min(int l, int r) { // 0-based, [l, r)
    assert(0 <= l and l <= r and r <= n);
    return range_get<MIN>(0, 0, n, l, r);
  }
  int64_t range_max(int l, int r) { // 0-based, [l, r)
    assert(0 <= l and l <= r and r <= n);
    return range_get<MAX>(0, 0, n, l, r);
  }
  int64_t range_sum(int l, int r) { // 0-based, [l, r)
    assert(0 <= l and l <= r and r <= n);
    return range_get<SUM>(0, 0, n, l, r);
  }

private:
  static constexpr char CHMIN = 0;
  static constexpr char CHMAX = 1;
  static constexpr char ADD = 2;
  static constexpr char UPDATE = 3;
  static constexpr char MIN = 10;
  static constexpr char MAX = 11;
  static constexpr char SUM = 12;

  template <char TYPE>
  void range_apply(int i, int il, int ir, int l, int r, int64_t g) {
    if (ir <= l or r <= il or break_condition<TYPE>(i, g)) {
      // break
    } else if (l <= il and ir <= r and tag_condition<TYPE>(i, g)) {
      tag<TYPE>(i, g);
    } else {
      pushdown(i);
      range_apply<TYPE>(2 * i + 1, il, (il + ir) / 2, l, r, g);
      range_apply<TYPE>(2 * i + 2, (il + ir) / 2, ir, l, r, g);
      update(i);
    }
  }
  template <char TYPE> inline bool break_condition(int i, int64_t g) {
    switch (TYPE) {
    case CHMIN:
      return a[i].max <= g;
    case CHMAX:
      return g <= a[i].min;
    case ADD:
      return false;
    case UPDATE:
      return false;
    default:
      assert(false);
    }
  }
  template <char TYPE> inline bool tag_condition(int i, int64_t g) {
    switch (TYPE) {
    case CHMIN:
      return a[i].max_second < g and g < a[i].max;
    case CHMAX:
      return a[i].min < g and g < a[i].min_second;
    case ADD:
      return true;
    case UPDATE:
      return true;
    default:
      assert(false);
    }
  }
  template <char TYPE> inline void tag(int i, int64_t g) {
    int length = n >> (32 - __builtin_clz(i + 1) - 1);
    if (TYPE == CHMIN) {
      if (a[i].max == a[i].min or g <= a[i].min) {
        tag<UPDATE>(i, g);
        return;
      }
      if (a[i].max != INT64_MIN) {
        a[i].sum -= a[i].max * a[i].max_count;
      }
      a[i].max = g;
      a[i].min_second = std::min(a[i].min_second, g);
      if (a[i].lazy_update != INT64_MAX) {
        a[i].lazy_update = std::min(a[i].lazy_update, g);
      }
      a[i].sum += g * a[i].max_count;
    } else if (TYPE == CHMAX) {
      if (a[i].max == a[i].min or a[i].max <= g) {
        tag<UPDATE>(i, g);
        return;
      }
      if (a[i].min != INT64_MAX) {
        a[i].sum -= a[i].min * a[i].min_count;
      }
      a[i].min = g;
      a[i].max_second = std::max(a[i].max_second, g);
      if (a[i].lazy_update != INT64_MAX) {
        a[i].lazy_update = std::max(a[i].lazy_update, g);
      }
      a[i].sum += g * a[i].min_count;
    } else if (TYPE == ADD) {
      if (a[i].max != INT64_MAX) {
        a[i].max += g;
      }
      if (a[i].max_second != INT64_MIN) {
        a[i].max_second += g;
      }
      if (a[i].min != INT64_MIN) {
        a[i].min += g;
      }
      if (a[i].min_second != INT64_MAX) {
        a[i].min_second += g;
      }
      a[i].lazy_add += g;
      if (a[i].lazy_update != INT64_MAX) {
        a[i].lazy_update += g;
      }
      a[i].sum += g * length;
    } else if (TYPE == UPDATE) {
      a[i].max = g;
      a[i].max_second = INT64_MIN;
      a[i].max_count = length;
      a[i].min = g;
      a[i].min_second = INT64_MAX;
      a[i].min_count = length;
      a[i].lazy_add = 0;
      a[i].lazy_update = INT64_MAX;
      a[i].sum = g * length;
    } else {
      assert(false);
    }
  }
  void pushdown(int i) {
    int l = 2 * i + 1;
    int r = 2 * i + 2;
    // update
    if (a[i].lazy_update != INT64_MAX) {
      tag<UPDATE>(l, a[i].lazy_update);
      tag<UPDATE>(r, a[i].lazy_update);
      a[i].lazy_update = INT64_MAX;
      return;
    }
    // add
    if (a[i].lazy_add != 0) {
      tag<ADD>(l, a[i].lazy_add);
      tag<ADD>(r, a[i].lazy_add);
      a[i].lazy_add = 0;
    }
    // chmin
    if (a[i].max < a[l].max) {
      tag<CHMIN>(l, a[i].max);
    }
    if (a[i].max < a[r].max) {
      tag<CHMIN>(r, a[i].max);
    }
    // chmax
    if (a[l].min < a[i].min) {
      tag<CHMAX>(l, a[i].min);
    }
    if (a[r].min < a[i].min) {
      tag<CHMAX>(r, a[i].min);
    }
  }
  void update(int i) {
    int l = 2 * i + 1;
    int r = 2 * i + 2;
    // chmin
    std::vector<int64_t> b{a[l].max, a[l].max_second, a[r].max,
                           a[r].max_second};
    std::sort(b.rbegin(), b.rend());
    b.erase(std::unique(ALL(b)), b.end());
    a[i].max = b[0];
    a[i].max_second = b[1];
    a[i].max_count = (b[0] == a[l].max ? a[l].max_count : 0) +
                     (b[0] == a[r].max ? a[r].max_count : 0);
    // chmax
    std::vector<int64_t> c{a[l].min, a[l].min_second, a[r].min,
                           a[r].min_second};
    std::sort(ALL(c));
    c.erase(std::unique(ALL(c)), c.end());
    a[i].min = c[0];
    a[i].min_second = c[1];
    a[i].min_count = (c[0] == a[l].min ? a[l].min_count : 0) +
                     (c[0] == a[r].min ? a[r].min_count : 0);
    // add
    a[i].lazy_add = 0;
    // update
    a[i].lazy_update = INT64_MAX;
    // sum
    a[i].sum = a[l].sum + a[r].sum;
  }

  template <char TYPE> int64_t range_get(int i, int il, int ir, int l, int r) {
    if (ir <= l or r <= il) {
      switch (TYPE) {
      case MIN:
        return INT64_MAX;
      case MAX:
        return INT64_MIN;
      case SUM:
        return 0;
      default:
        assert(false);
      }
    } else if (l <= il and ir <= r) {
      // base
      switch (TYPE) {
      case MIN:
        return a[i].min;
      case MAX:
        return a[i].max;
      case SUM:
        return a[i].sum;
      default:
        assert(false);
      }
    } else {
      pushdown(i);
      int64_t value_l = range_get<TYPE>(2 * i + 1, il, (il + ir) / 2, l, r);
      int64_t value_r = range_get<TYPE>(2 * i + 2, (il + ir) / 2, ir, l, r);
      // mult
      switch (TYPE) {
      case MIN:
        return std::min(value_l, value_r);
      case MAX:
        return std::max(value_l, value_r);
      case SUM:
        return value_l + value_r;
      default:
        assert(false);
      }
    }
  }
};

signed main() {
  i64 n, q;
  cin >> n >> q;
  /*
  if(n == 3){
      if(q)
          cout << 0 << endl;
      else
          cout << 1 << endl;
      return 0;
  }
   */
  segment_tree_beats seg1(n - 1);
  segment_tree_beats seg2(n - 1);
  seg1.range_add(0, n - 1, n - 2);
  seg2.range_add(0, n - 1, n - 2);
  i64 ans = (n - 2) * (n - 2);
  for (int i = 0; i < q; ++i) {
    int ty, x;
    cin >> ty >> x;
    x -= 2;
    if (ty == 1) {
      i64 v = seg1.range_min(x, x + 1);
      ans -= v;
      seg2.range_chmin(0, v, x);
    } else {
      i64 v = seg2.range_min(x, x + 1);
      ans -= v;
      seg1.range_chmin(0, v, x);
    }
  }
  cout << ans << endl;
}