From e254c0f0cd905da6ecdcddb81506be150968bac4 Mon Sep 17 00:00:00 2001 From: subcrip Date: Thu, 12 Dec 2024 11:20:18 +0000 Subject: [PATCH] Add trees/segtree_persistent.cc Signed-off-by: subcrip --- trees/segtree_persistent.cc | 87 +++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 trees/segtree_persistent.cc diff --git a/trees/segtree_persistent.cc b/trees/segtree_persistent.cc new file mode 100644 index 0000000..d7e2a9c --- /dev/null +++ b/trees/segtree_persistent.cc @@ -0,0 +1,87 @@ +template struct segtree { + using info_type = Addable_Info; + using size_type = size_t; + struct Node { + size_type lson, rson; + info_type info; + }; + vector d; + vector version_root; + size_type _max; + + void _copy(size_type& virt) { + int o = virt; + virt = d.size(); + d.emplace_back(); + if (o != 0) d.back() = d[o]; + } + explicit segtree(size_type&& _max) : d(1), _max(_max - 1) { + version_root.emplace_back(0); + } + segtree(const vector& init) : d(1), _max(init.size() - 1) { + version_root.emplace_back(0); + auto dfs = [&] (auto dfs, size_type s, size_type t, size_type p) -> void { + if (s == t) { + d[p].info = init[s]; + return; + } + int m = s + t >> 1; + _copy(d[p].lson), _copy(d[p].rson); + dfs(dfs, s, m, d[p].lson); + dfs(dfs, m + 1, t, d[p].rson); + }; + dfs(dfs, 0, _max, version_root[0]); + } + void _set(size_type s, size_type t, size_type p, size_type x, const info_type& c) { + if (s == t) { + d[p].info = c; + return; + } + size_type m = s + (t - s >> 1); + if (x <= m) { + _copy(d[p].lson); + _set(s, m, d[p].lson, x, c); + } else { + _copy(d[p].rson); + _set(m + 1, t, d[p].rson, x, c); + } + } + size_type _clone(size_type version) { + d.emplace_back(d[version_root[version]]); + version_root.emplace_back(d.size() - 1); + return version_root.size() - 1; + } + size_type set(size_type version, size_type loc, const info_type& c) { + size_type new_version = _clone(version); + _set(0, _max, version_root[new_version], loc, c); + return new_version; + } + info_type _range_query(size_type s, size_type t, size_type p, size_type l, size_type r) { + if (l <= s and t <= r) { + return d[p].info; + } + size_type m = s + (t - s >> 1); + info_type ret = {}; + if (l <= m and d[p].lson != 0) { + ret = ret + _range_query(s, m, d[p].lson, l, r); + } + if (r > m and d[p].rson != 0) { + ret = ret + _range_query(m + 1, t, d[p].rson, l, r); + } + return ret; + } + info_type range_query(size_type version, size_type l, size_type r) { + return _range_query(0, _max, version_root[version], l, r); + } + info_type query(size_type version, size_type loc) { + return range_query(version, loc, loc); + } +}; + +struct Info { + int val; +}; + +Info operator+(const Info& lhs, const Info& rhs) { + return { lhs.val + rhs.val }; +}