#include #include template struct SegmentTreeBase { explicit SegmentTreeBase(int n_) : n(n_), nodes(n << 1) {} Node &root() { return get_node(0, n - 1); } const Node &root() const { return get_node(0, n - 1); } template H traverse_all(H &&h) { traverse_all(std::forward(h), 0, n - 1); return h; } template H traverse(H &&h, int a, int b) { traverse(std::forward(h), 0, n - 1, a, b); return h; } template H reverse_traverse(H &&h, int a, int b) { traverse(std::forward(h), 0, n - 1, a, b); return h; } Node &get_node(int l, int r) { return nodes[l + r | (l != r)]; } protected: template void traverse_all(Op &&op, int l, int r) { Node &n = get_node(l, r); op(l, r, n); if (l < r) { int m = (l + r) >> 1; Node &ln = get_node(l, m); Node &rn = get_node(m + 1, r); static_cast(this)->propagate(l, m, r, n, ln, rn); traverse_all(std::forward(op), l, m); traverse_all(std::forward(op), m + 1, r); static_cast(this)->collect(l, m, r, n, ln, rn); } } template void traverse(Op &&op, int l, int r, int a, int b) { if (b < l || r < a) { return; } Node &n = get_node(l, r); if (a <= l && r <= b) { op(l, r, n); } else { int m = (l + r) >> 1; Node &ln = get_node(l, m); Node &rn = get_node(m + 1, r); static_cast(this)->propagate(l, m, r, n, ln, rn); if (direction) { traverse(std::forward(op), m + 1, r, a, b); traverse(std::forward(op), l, m, a, b); } else { traverse(std::forward(op), l, m, a, b); traverse(std::forward(op), m + 1, r, a, b); } static_cast(this)->collect(l, m, r, n, ln, rn); } } int n; std::vector nodes; };