From c5f62c3e45747bad3e5d06f53435c12ed226a308 Mon Sep 17 00:00:00 2001 From: Ariel Date: Thu, 1 Feb 2024 22:34:51 +0800 Subject: [PATCH] Create segtreed.cc --- trees/segtreed.cc | 53 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 trees/segtreed.cc diff --git a/trees/segtreed.cc b/trees/segtreed.cc new file mode 100644 index 0000000..36f8694 --- /dev/null +++ b/trees/segtreed.cc @@ -0,0 +1,53 @@ +template class segtreed { +private: + using size_type = __uint64_t; + size_type cnt, root; + T _max; + vector d, b; + vector ls, rs; + + void _update(size_type s, size_type t, size_type &p, size_type l, size_type r, T c) { + if (!p) p = ++cnt; + if (l <= s && t <= r) { + d[p] += c * (t - s + 1); + b[p] += c; + return; + } + size_type m = s + (t - s >> 1); + if (!ls[p]) ls[p] = ++cnt; + if (!rs[p]) rs[p] = ++cnt; + if (b[p] && s != t) { + d[ls[p]] += b[p] * (m - s + 1), d[rs[p]] += b[p] * (t - m); + b[ls[p]] += b[p], b[rs[p]] += b[p]; + b[p] = 0; + } + if (l <= m) _update(s, m, ls[p], l, r, c); + if (r > m) _update(m + 1, t, rs[p], l, r, c); + d[p] = d[ls[p]] + d[rs[p]]; + } + + T _query(size_type s, size_type t, size_type p, size_type l, size_type r) { + if (!p) return {}; + if (l <= s && t <= r) return d[p]; + size_type m = s + (t - s >> 1); + T res = {}; + if (b[p]) { + d[ls[p]] += b[p] * (m - s + 1), d[rs[p]] += b[p] * (t - m); + b[ls[p]] += b[p], b[rs[p]] += b[p]; + b[p] = 0; + } + if (l <= m) res += _query(s, m, ls[p], l, r); + if (r > m) res += _query(m + 1, t, rs[p], l, r); + return res; + } +public: + segtreed(size_type n, T _max) : cnt(0), root(0), d(4 * n, {}), b(4 * n, {}), ls(4 * n, 0), rs(4 * n, 0), _max(_max) {} + + void update(size_type l, size_type r, T c) { + _update({}, _max, root, l, r, c); + } + + T query(size_type l, size_type r) { + return _query({}, _max, root, l, r); + } +};