5 #ifndef YGG_DYNAMIC_SEGMENT_TREE_HPP 6 #define YGG_DYNAMIC_SEGMENT_TREE_HPP 11 #include "size_holder.hpp" 14 #include "ziptree.hpp" 19 template <
class Node,
class NodeTraits,
class Combiners,
class Options,
20 class TreeSelector,
class Tag>
23 namespace dyn_segtree_internal {
27 template <
class InnerNode,
class KeyT_in>
39 get_key(
const KeyT_in query) noexcept
45 get_key(
const std::pair<KeyT_in, bool> & query) noexcept
47 return std::get<0>(query);
53 template <
class InnerNode>
55 template <
class InnerTree,
class InnerNode,
class Node,
class NodeTraits>
56 class InnerRBNodeTraits;
57 template <
class InnerTree,
class InnerNode,
class AggValueT>
58 class InnerZNodeTraits;
59 template <
class InnerTree,
class InnerNode,
class Node,
class AggValueT>
60 class InnerWBNodeTraits;
77 template <
class... AdditionalOptions>
80 template <
class InnerNode,
class KeyT>
81 using Options = TreeOptions<TreeFlags::MULTIPLE,
82 TreeFlags::BENCHMARK_SEQUENCE_INTERFACE<
84 AdditionalOptions...>;
87 struct InnerNodeBaseBuilder
89 template <
class InnerNodeCRTP,
class KeyT>
94 template <
class CRTP,
class Node,
class NodeTraits,
class InnerNode,
98 dyn_segtree_internal::InnerRBNodeTraits<CRTP, InnerNode, Node,
100 Options<InnerNode, typename InnerNode::KeyT>,
101 dyn_segtree_internal::InnerRBTTag<Tag>, Compare<InnerNode>>;
103 template <
class TagType>
104 using Tag = InnerRBTTag<TagType>;
110 template <
class... AdditionalOptions>
113 template <
class InnerNode,
class KeyT>
114 using Options = TreeOptions<TreeFlags::MULTIPLE, TreeFlags::WBT_SINGLE_PASS,
115 TreeFlags::BENCHMARK_SEQUENCE_INTERFACE<
117 AdditionalOptions...>;
120 struct InnerNodeBaseBuilder
122 template <
class InnerNodeCRTP,
class KeyT>
127 template <
class CRTP,
class Node,
class NodeTraits,
class InnerNode,
131 dyn_segtree_internal::InnerWBNodeTraits<CRTP, InnerNode, Node,
133 Options<InnerNode, typename InnerNode::KeyT>,
134 dyn_segtree_internal::InnerWBTTag<Tag>, Compare<InnerNode>>;
136 template <
class TagType>
137 using Tag = InnerWBTTag<TagType>;
143 template <
class... AdditionalOptions>
146 template <
class InnerNode,
class KeyT>
148 TreeOptions<TreeFlags::MULTIPLE, TreeFlags::ZTREE_RANK_TYPE<uint8_t>,
149 TreeFlags::BENCHMARK_SEQUENCE_INTERFACE<
151 AdditionalOptions...>;
153 struct InnerNodeBaseBuilder
155 template <
class InnerNodeCRTP,
class KeyT>
160 template <
class CRTP,
class Node,
class NodeTraits,
class InnerNode,
164 dyn_segtree_internal::InnerZNodeTraits<
166 Options<InnerNode, typename InnerNode::KeyT>,
167 dyn_segtree_internal::InnerZTTag<Tag>, Compare<InnerNode>>;
169 template <
class TagType>
170 using Tag = InnerZTTag<TagType>;
181 template <
template <
class InnerNodeCRTP,
class BaseKeyT>
class Base,
182 class OuterNode,
class KeyT_in,
class ValueT_in,
class AggValueT_in,
183 class Combiners,
class Tag>
184 class InnerNode :
public Base<InnerNode<Base, OuterNode, KeyT_in, ValueT_in,
185 AggValueT_in, Combiners, Tag>,
207 KeyT get_point() const noexcept;
214 bool is_start() const noexcept;
221 bool is_end() const noexcept;
229 bool is_closed() const noexcept;
240 const OuterNode * get_interval() const noexcept;
253 OuterNode * container;
261 template <class FNode, class FNodeTraits, class FCombiners, class FOptions,
262 class TreeSelector, class FTag>
264 template <class FInnerTree, class FInnerNode, class FNode, class FNodeTraits>
265 friend class InnerRBNodeTraits;
266 template <class FInnerTree, class FInnerNode, class FNode, class FNodeTraits>
267 friend class InnerWBNodeTraits;
268 template <class FInnerTree, class FInnerNode, class FAggValueT>
269 friend class InnerZNodeTraits;
272 template <class FInnerNode, class... FCombiners>
273 friend class ASCIIInnerNodeNameGetter;
274 template <class FInnerNode, class... FCombiners>
275 friend class DOTInnerNodeNameGette;
281 class InnerZNodeTraits {
292 void init_zipping(
const InnerNode * to_be_deleted) noexcept;
293 void before_zip_from_left(InnerNode * left_head) noexcept;
294 void before_zip_from_right(InnerNode * right_head) noexcept;
295 void before_zip_tree_from_left(InnerNode * left_head)
const noexcept;
296 void before_zip_tree_from_right(InnerNode * right_head)
const noexcept;
297 void zipping_ended_left_without_tree(InnerNode * prev_left_head)
const 299 void zipping_ended_right_without_tree(InnerNode * prev_right_head)
const 301 void zipping_done(InnerNode * head, InnerNode * tail)
const noexcept;
302 void delete_without_zipping(
const InnerNode * to_be_deleted)
const noexcept;
307 InnerNode * unzip_left_last;
308 InnerNode * unzip_right_last;
309 bool unzip_left_first;
310 bool unzip_right_first;
312 void init_unzipping(InnerNode * to_be_inserted) noexcept;
313 void unzip_to_left(InnerNode * n) noexcept;
314 void unzip_to_right(InnerNode * n) noexcept;
315 void unzip_done(InnerNode * unzip_root, InnerNode * left_spine_end,
316 InnerNode * right_spine_end) noexcept;
319 template <
class InnerTree,
class InnerNode,
class Node,
class NodeTraits>
322 template <
class RBTreeBase>
323 static void leaf_inserted(
const InnerNode & node,
324 const RBTreeBase & t) noexcept;
325 template <
class RBTreeBase>
326 static void rotated_left(
InnerNode & node,
const RBTreeBase & t) noexcept;
327 template <
class RBTreeBase>
328 static void rotated_right(
InnerNode & node,
const RBTreeBase & t) noexcept;
329 template <
class RBTreeBase>
330 static void delete_leaf(
const InnerNode & node,
331 const RBTreeBase & t) noexcept;
332 template <
class RBTreeBase>
343 template <
class InnerTree,
class InnerNode,
class Node,
class NodeTraits>
344 class InnerWBNodeTraits
345 :
public InnerRBNodeTraits<InnerTree, InnerNode, Node, NodeTraits> {
347 template <
class WBTreeBase>
348 static void splice_out_left_knee(
350 const WBTreeBase & t) noexcept;
351 template <
class WBTreeBase>
354 const WBTreeBase & t) noexcept;
357 template <
class InnerNode>
360 using PointDescription =
361 std::pair<const typename InnerNode::KeyT, const int_fast8_t>;
368 bool operator()(
const PointDescription & lhs,
const InnerNode & rhs)
const 370 bool operator()(
const InnerNode & lhs,
const PointDescription & rhs)
const 377 template <
class InnerNode,
class... Combiners>
378 class ASCIIInnerNodeNameGetter {
380 std::string get_name(
InnerNode * node)
const;
383 template <
class InnerNode,
class... Combiners>
384 class DOTInnerNodeNameGetter {
386 std::string get_name(
InnerNode * node)
const;
389 template <
class InnerNode>
390 class DOTInnerEdgeNameGetter {
392 std::string get_name(
InnerNode * node,
bool left)
const;
409 template <
class... AdditionalOptions>
410 class UseRBTree :
public dyn_segtree_internal::UseRBTree<AdditionalOptions...> {
425 template <
class... AdditionalOptions>
427 :
public dyn_segtree_internal::UseZipTree<AdditionalOptions...> {
442 template <
class... AdditionalOptions>
443 class UseWBTree :
public dyn_segtree_internal::UseWBTree<AdditionalOptions...> {
457 template <
class KeyType,
class ValueType>
460 using ValueT = ValueType;
461 using KeyT = KeyType;
484 bool collect_left(
const KeyT my_point,
const MyType * left_child_combiner,
485 const ValueType edge_val);
506 bool collect_right(
const KeyT my_point,
const MyType * right_child_combiner,
507 const ValueType edge_val);
522 bool traverse_left_edge_up(
const KeyT new_point,
const ValueT edge_val);
535 bool traverse_right_edge_up(
const KeyT new_point,
const ValueT edge_val);
559 bool rebuild(KeyT my_point,
const MyType * left_child_combiner,
560 ValueT left_edge_val,
const MyType * right_child_combiner,
561 ValueT right_edge_val);
568 ValueT
get()
const noexcept;
574 return "MaxCombiner";
578 get_dbg_value()
const 580 return std::to_string(this->val);
586 ValueT child_value(
const MyType * child)
const noexcept;
601 template <
class KeyType,
class ValueType>
604 using ValueT = ValueType;
605 using KeyT = KeyType;
631 bool collect_left(KeyT my_point,
const MyType * left_child_combiner,
653 bool collect_right(KeyT my_point,
const MyType * right_child_combiner,
669 bool traverse_left_edge_up(KeyT new_point, ValueT edge_val);
682 bool traverse_right_edge_up(KeyT new_point, ValueT edge_val);
706 bool rebuild(KeyT my_point,
const MyType * left_child_combiner,
707 ValueT left_edge_val,
const MyType * right_child_combiner,
708 ValueT right_edge_val);
715 ValueT
get()
const noexcept;
730 bool is_left_border_valid()
const noexcept;
744 bool is_right_border_valid()
const noexcept;
755 KeyT get_left_border()
const noexcept;
766 KeyT get_right_border()
const noexcept;
772 return "RangedMaxCombiner";
776 get_dbg_value()
const 778 std::string res = std::to_string(this->val) + std::string(
"@[");
779 if (this->left_border_valid) {
780 res += std::to_string(this->left_border);
782 res += std::string(
"--");
785 if (this->right_border_valid) {
786 res += std::to_string(this->right_border);
800 bool left_border_valid;
802 bool right_border_valid;
804 ValueT child_value(
const MyType * child)
const noexcept;
821 template <
class KeyT,
class AggValueT,
class... Combiners>
844 bool rebuild(KeyT my_point,
const MyType * left_child,
845 AggValueT left_edge_val,
const MyType * right_child,
846 AggValueT right_edge_val);
849 bool collect_left(KeyT my_point,
const MyType * left_child_combiner,
851 bool collect_right(KeyT my_point,
const MyType * right_child_combiner,
855 bool traverse_left_edge_up(KeyT new_point, AggValueT edge_val);
856 bool traverse_right_edge_up(KeyT new_point, AggValueT edge_val);
867 template <
class Combiner>
868 typename Combiner::ValueT
get()
const;
876 template <
class Combiner>
877 const Combiner & get_combiner()
const;
879 using pack = std::tuple<Combiners...>;
882 template <
class Combiner>
883 const Combiner * child_combiner(
const MyType * child)
const;
885 std::tuple<Combiners...> data;
888 template <
class KeyT,
class AggValueT>
912 template <
class KeyType,
class ValueType,
class AggValueType,
class Combiners,
918 using KeyT = KeyType;
919 using ValueT = ValueType;
920 using AggValueT = AggValueType;
922 Combiners, TreeSelector, Tag>;
925 TreeSelector::template InnerNodeBaseBuilder<
926 typename TreeSelector::template Tag<Tag>>::template Base,
927 MyClass, KeyT, ValueT, AggValueT, Combiners, Tag>;
956 template <
class Node>
962 using KeyT =
typename Node::KeyT;
976 static KeyT get_lower(
const Node & n);
985 static KeyT get_upper(
const Node & n);
1020 static ValueT get_value(
const Node & n);
1065 template <
class Node,
class NodeTraits,
class Combiners,
1073 typename Node::AggValueT, Combiners,
1075 using InnerNode =
typename NB::InnerNode;
1078 "NodeTraits not properly derived from DynSegTreeNodeTraits!");
1079 static_assert(std::is_base_of<NB, Node>::value,
1080 "Node class not properly derived from DynSegTreeNodeBase!");
1081 static_assert(Options::multiple,
1082 "DynamicSegmentTree always allows multiple equal intervals.");
1085 using KeyT =
typename Node::KeyT;
1086 using ValueT =
typename Node::ValueT;
1087 using AggValueT =
typename Node::AggValueT;
1093 :
public TreeSelector::template BaseTree<InnerTree, Node, NodeTraits,
1097 typename TreeSelector::template BaseTree<InnerTree, Node, NodeTraits,
1100 using BaseTree::BaseTree;
1102 void modify_contour(InnerNode * left, InnerNode * right,
ValueT val);
1105 std::pair<std::vector<InnerNode *>, std::vector<InnerNode *>>;
1106 void build_lca(InnerNode * left, InnerNode * right)
const;
1108 static bool rebuild_combiners_at(InnerNode * n);
1109 static void rebuild_combiners_recursively(InnerNode * n);
1113 mutable size_t generation = 0;
1126 mutable std::vector<InnerNode *> contour_left_path;
1135 mutable std::vector<InnerNode *> contour_right_path;
1157 void insert(Node & n);
1166 void remove(Node & n);
1186 AggValueT query(
const typename Node::KeyT & x)
const noexcept;
1188 template <
class Combiner>
1189 Combiner get_combiner()
const;
1191 template <
class Combiner>
1192 Combiner get_combiner(
const typename Node::KeyT & lower,
1193 const typename Node::KeyT & upper,
1194 bool lower_closed =
true,
1195 bool upper_closed =
false)
const;
1197 template <
class Combiner>
1198 typename Combiner::ValueT get_combined()
const;
1200 template <
class Combiner>
1201 typename Combiner::ValueT get_combined(
const typename Node::KeyT & lower,
1202 const typename Node::KeyT & upper,
1203 bool lower_closed =
true,
1204 bool upper_closed =
false)
const;
1209 template <
bool reverse>
1210 using const_iterator =
typename InnerTree::template const_iterator<reverse>;
1211 template <
bool reverse>
1212 using iterator =
typename InnerTree::template iterator<reverse>;
1222 const_iterator<false> cbegin()
const;
1228 const_iterator<false> cend()
const;
1234 const_iterator<false> begin()
const;
1235 iterator<false> begin();
1242 const_iterator<false> end()
const;
1243 iterator<false> end();
1250 const_iterator<true> crbegin()
const;
1256 const_iterator<true> crend()
const;
1262 const_iterator<true> rbegin()
const;
1263 iterator<true> rbegin();
1270 const_iterator<true> rend()
const;
1271 iterator<true> rend();
1281 const_iterator<false>
1282 lower_bound_event(
const typename Node::KeyT & key)
const;
1283 iterator<false> lower_bound_event(
const typename Node::KeyT & key);
1293 const_iterator<false>
1294 upper_bound_event(
const typename Node::KeyT & key)
const;
1295 iterator<false> upper_bound_event(
const typename Node::KeyT & key);
1309 void dbg_verify()
const;
1311 template <
class Combiner>
1312 void dbg_verify_max_combiner()
const;
1316 template <
class... Ts>
1317 using NodeNameGetterCurried =
1318 dyn_segtree_internal::ASCIIInnerNodeNameGetter<InnerNode, Ts...>;
1319 using NodeNameGetter =
1320 typename utilities::pass_pack<
typename Combiners::pack,
1321 NodeNameGetterCurried>::type;
1322 template <
class... Ts>
1323 using DotNameGetterCurried =
1324 dyn_segtree_internal::DOTInnerNodeNameGetter<InnerNode, Ts...>;
1325 using DotNameGetter =
1326 typename utilities::pass_pack<
typename Combiners::pack,
1327 DotNameGetterCurried>::type;
1329 using TreePrinter = debug::TreePrinter<InnerNode, NodeNameGetter>;
1330 using TreeDotExporter = debug::TreeDotExport<
1331 InnerNode, DotNameGetter,
1332 dyn_segtree_internal::DOTInnerEdgeNameGetter<InnerNode>>;
1336 void dbg_print_inner_tree()
const;
1337 std::stringstream & dbg_get_dot()
const;
1340 void apply_interval(Node & n);
1341 void unapply_interval(Node & n);
1345 void dbg_verify_all_points()
const;
1346 void dbg_verify_start_end()
const;
1351 #ifndef YGG_DYNAMIC_SEGMENT_TREE_CPP 1352 #include "dynamic_segment_tree.cpp" 1355 #endif // YGG_DYNAMIC_SEGMENT_TREE_HPP typename Node::ValueT ValueT
Definition: dynamic_segment_tree.hpp:967
A combiner that allows to retrieve the maximum value over any range.
Definition: dynamic_segment_tree.hpp:458
Base class (template) to supply your node class with metainformation.
Definition: wbtree.hpp:36
static bool is_lower_closed(const Node &n)
Definition: dynamic_segment_tree.hpp:994
Representation of either a start or an end of an interval.
Definition: dynamic_segment_tree.hpp:184
static bool is_upper_closed(const Node &n)
Definition: dynamic_segment_tree.hpp:1007
The Zip Tree.
Definition: ziptree.hpp:194
A combiner that allows to retrieve the maximum value over any range plus the range over which the max...
Definition: dynamic_segment_tree.hpp:602
Helper base class for the NodeTraits you need to implement.
Definition: rbtree.hpp:120
The Weight Balanced Tree.
Definition: wbtree.hpp:142
Base class (template) to supply your node class with metainformation.
Definition: rbtree.hpp:92
AggValueT_in AggValueT
The type of the aggregate value.
Definition: dynamic_segment_tree.hpp:199
typename Node::KeyT KeyT
Definition: dynamic_segment_tree.hpp:962
Definition: dynamic_segment_tree.hpp:28
KeyT_in KeyT
The type of the key (i.e., the interval bounds)
Definition: dynamic_segment_tree.hpp:191
Base class (template) to supply your node class with metainformation.
Definition: dynamic_segment_tree.hpp:914
The Red-Black Tree.
Definition: rbtree.hpp:194
Class used to select the weight balanced tree as underlying tree for the DynamicSegmentTree.
Definition: dynamic_segment_tree.hpp:443
Class used to select the red-black tree as underlying tree for the DynamicSegmentTree.
Definition: dynamic_segment_tree.hpp:410
This class represents the pack of combiners associated with every node of a Dynamic Segment Tree...
Definition: dynamic_segment_tree.hpp:822
Base class (template) to supply your node class with metainformation.
Definition: ziptree.hpp:21
You must derive your own traits class from this class template, telling the DynamicSegmentTree how to...
Definition: dynamic_segment_tree.hpp:957
The Dynamic Segment Tree class.
Definition: dynamic_segment_tree.hpp:21
ValueT_in ValueT
The type of the value associated with the intervals.
Definition: dynamic_segment_tree.hpp:195
KeyT get_point() const noexcept
Returns the point at which the event represented by this InnerNode happens.
Class used to select the Zip Tree tree as underlying tree for the DynamicSegmentTree.
Definition: dynamic_segment_tree.hpp:426
Definition: rbtree.hpp:18