#include using i64 = long long; template class LazySegmentTree { int size; T tid; T *dat; U uid; U *lazy; inline T f(T a, T b) { auto [na, la, ra] = a; auto [nb, lb, rb] = b; int n = na + nb + (ra >= 0 && ra == lb); return std::make_tuple(n, la, rb); } inline T g(T t, U u, int len) { auto [n, l, r] = t; return std::make_tuple(n, l + u, r + u); } inline U h(U a, U b) { return a + b; } void propagate(int k, int l, int r) { if (lazy[k] == uid) return; if (k < size - 1) { lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]); lazy[2 * k + 2] = h(lazy[2 * k + 2], lazy[k]); } dat[k] = g(dat[k], lazy[k], r - l); lazy[k] = uid; } T update_impl(int a, int b, U x, int k, int l, int r) { propagate(k, l, r); if (r <= a || b <= l) return dat[k]; if (a <= l && r <= b) { lazy[k] = h(lazy[k], x); propagate(k, l, r); return dat[k]; } return dat[k] = f(update_impl(a, b, x, 2 * k + 1, l, (l + r) / 2), update_impl(a, b, x, 2 * k + 2, (l + r) / 2, r)); } T query_impl(int a, int b, int k, int l, int r) { propagate(k, l, r); if (r <= a || b <= l) return tid; if (a <= l && r <= b) return dat[k]; return f(query_impl(a, b, 2 * k + 1, l, (l + r) / 2), query_impl(a, b, 2 * k + 2, (l + r) / 2, r)); } public: LazySegmentTree(const int n, const T &tid, const U &uid) : tid(tid), uid(uid) { size = 2; while (size < n) size *= 2; dat = new T[2 * size - 1]; lazy = new U[2 * size - 1]; for (int i = 0; i < 2 * size - 1; i++) { dat[i] = tid; lazy[i] = uid; } } template