118 template <
class GT,
class SA>
125 static constexpr size_t NONE = std::numeric_limits<size_t>::max();
157 return std::make_pair(u, v);
167 <<
"HLD_Tree_Data: root node provided but graph is empty";
180 Node * p = it.get_curr();
187 <<
"HLD_Tree_Data: failed to index all graph nodes";
189 if (
root_ ==
nullptr)
193 <<
"HLD_Tree_Data: root node does not belong to graph";
205 for (
size_t i = 0; i <
n_; ++i)
213 Arc * a = it.get_curr_ne();
221 <<
"HLD_Tree_Data: arc endpoint is not indexed";
227 <<
"HLD_Tree_Data: self-loop detected in filtered graph";
231 <<
"HLD_Tree_Data: parallel/duplicate edge detected in filtered graph";
238 <<
"HLD_Tree_Data: filtered graph is not a tree (expected "
242 it.has_curr(); it.next_ne())
244 const auto & [
fst,
snd] = it.get_curr();
245 const size_t u =
fst.first;
246 const size_t v =
fst.second;
261 for (
size_t i = 0; i <
n_; ++i)
268 for (
size_t i = 0; i <
n_; ++i)
289 auto &
fr = stack.
top();
295 const size_t done =
fr.node;
303 if (
nxt ==
fr.parent)
307 <<
"HLD_Tree_Data: filtered graph is not acyclic";
319 <<
"HLD_Tree_Data: filtered graph is not connected";
327 for (
size_t u = 0; u <
n_; ++u)
337 for (
size_t i = 0; i < adj.size(); ++i)
339 const size_t v = adj(i);
397 auto &
fr = stack.
top();
409 if (
nxt ==
fr.parent)
419 if (adj.size() > 0
and adj(0) ==
fr.parent)
446 <<
where <<
": id=" <<
id <<
" is out of range [0, " <<
n_ <<
")";
478 <<
"HLD_Tree_Data::id_of: null node";
482 <<
"HLD_Tree_Data::id_of: node does not belong to graph";
489 check_id(
id,
"HLD_Tree_Data::node_of");
524 template <
class GT,
typename T,
class Op,
class SA = Dft_Show_Arc<GT>>
548 template <
class NodeValueFn>
555 for (
size_t i = 0; i <
n(); ++i)
558 for (
size_t id = 0;
id <
n(); ++id)
579 template <
class NodeValueFn>
581 const T & identity, Op
oper = Op(),
SA sa =
SA())
591 template <
class NodeValueFn>
593 const T & identity, Op
oper = Op(),
SA sa =
SA())
861 const size_t a =
lca_id(u, v);
940 template <
class GT,
typename T,
class SA = Dft_Show_Arc<GT>>
946 template <
class NodeValueFn>
952 template <
class NodeValueFn>
967 template <
class GT,
typename T,
class SA = Dft_Show_Arc<GT>>
973 template <
class NodeValueFn>
979 template <
class NodeValueFn>
994 template <
class GT,
typename T,
class SA = Dft_Show_Arc<GT>>
1000 template <
class NodeValueFn>
1006 template <
class NodeValueFn>
Exception handling system with formatted messages for Aleph-w.
#define ah_runtime_error_unless(C)
Throws std::runtime_error if condition does NOT hold.
#define ah_out_of_range_error_if(C)
Throws std::out_of_range if condition holds.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
#define ah_invalid_argument_if(C)
Throws std::invalid_argument if condition holds.
Simple dynamic array with automatic resizing and functional operations.
static Array create(size_t n)
Create an array with n logical elements.
Dynamic stack of elements of generic type T based on a singly linked list.
T & top()
Return a modifiable reference to the top item of the stack.
bool is_empty() const noexcept
Check if the stack is empty.
T pop()
Remove and return the top item of the stack.
T & push(const T &data)
Push an item by copy onto the top of the stack.
Generic key-value map implemented on top of a binary search tree.
typename Base::Iterator Iterator
void next_ne() noexcept
Advances the iterator to the next filtered element (noexcept version).
Heavy-Light Decomposition with segment tree for path/subtree queries.
static constexpr size_t NONE
void point_update_id(const size_t v, const T &new_value)
Point update by node ID: set value to new_value.
size_t distance(const Node *u, const Node *v) const
Number of edges between two nodes in O(log n).
T path_query(const Node *u, const Node *v) const
Path query by node pointers in O(log^2 n).
T path_query_id(size_t u, size_t v) const
Path query by node IDs in O(log^2 n).
size_t chain_head_id(const size_t id) const
Head of the chain containing node id.
Node * node_of(const size_t id) const
Map an internal ID back to a Node pointer.
size_t depth_of_id(const size_t id) const
Depth of node id from root.
size_t subtree_size_of_id(const size_t id) const
Subtree size of node id.
size_t num_chains() const noexcept
Number of heavy chains in the decomposition.
T get_value(const Node *v) const
Current node value at node pointer v.
size_t id_of(const Node *node) const
Map a Node pointer to its internal ID.
size_t size() const noexcept
Total number of nodes in the tree.
const Array< size_t > & position_array() const noexcept
Read-only access to the flat-position array.
Node * lca(const Node *u, const Node *v) const
LCA query by node pointers in O(log n).
size_t parent_id(const size_t id) const
Parent ID of node id, or NONE if root.
Gen_HLD(const GT &g, Node *root, NodeValueFn &&node_value, const T &identity, Op oper=Op(), SA sa=SA())
Construct HLD from graph, root, and node value functor.
void point_update(const Node *v, const T &new_value)
Point update by node pointer: set value to new_value.
size_t position(const size_t id) const
HLD flat-array position of node id.
size_t lca_id(size_t u, size_t v) const
LCA query by node IDs in O(log n).
void ensure_not_empty(const char *where) const
size_t root_id() const noexcept
Returns the internal ID of the root node.
const Array< size_t > & subtree_size_array() const noexcept
Read-only access to the subtree-size array.
void build_segment_tree(NodeValueFn &&node_value)
T subtree_query(const Node *v) const
Subtree query by node pointer in O(log n).
size_t subtree_size_of(const Node *node) const
Subtree size of node.
T path_query_edges_id(size_t u, size_t v) const
Edge-weighted path query by node IDs in O(log^2 n).
bool is_empty() const noexcept
Returns true if the tree has no nodes.
size_t depth_of(const Node *node) const
Depth of node from root.
Gen_Segment_Tree< T, Op > seg_
const Array< size_t > & depth_array() const noexcept
Read-only access to the depth array.
size_t n() const noexcept
T subtree_query_id(const size_t v) const
Subtree query by node ID in O(log n).
const Array< size_t > & parent_array() const noexcept
Read-only access to the parent array.
size_t distance_id(const size_t u, const size_t v) const
Number of edges between two nodes by IDs in O(log n).
Gen_HLD(const GT &g, NodeValueFn &&node_value, const T &identity, Op oper=Op(), SA sa=SA())
Construct with first graph node as root.
Node * root() const noexcept
Returns the root node.
Node * parent_of(const Node *node) const
Parent of node, or nullptr if root.
T get_value_at_id(const size_t id) const
Current node value at HLD position pos in the segment tree.
T path_query_edges(const Node *u, const Node *v) const
Edge-weighted path query by node pointers.
const Array< size_t > & chain_head_array() const noexcept
Read-only access to the chain-head array.
Segment tree over an arbitrary associative binary operation.
Graph_Node< Node_Info > Node
The graph type.
Graph_Arc< Arc_Info > Arc
The node class type.
Filtered iterator on the nodes of a graph.
const Array< size_t > & tout() const noexcept
Array< Node * > id_to_node_
const Array< size_t > & chain_head() const noexcept
void validate_id(const size_t id, const char *where) const
const Array< size_t > & parent() const noexcept
void compute_hld_positions()
const Array< size_t > & tin() const noexcept
HLD_Tree_Data(const GT &g, Node *root, SA sa=SA())
const Array< size_t > & subtree_size() const noexcept
static Pair_Key normalize_pair(size_t u, size_t v) noexcept
void compute_sizes_and_parents()
Array< Array< size_t > > adjacency_
size_t root_id() const noexcept
const Array< Node * > & id_to_node() const noexcept
Node * node_of(const size_t id) const
Array< size_t > chain_head_
Node * root() const noexcept
size_t id_of(const Node *node) const
static constexpr size_t NONE
const Array< size_t > & depth() const noexcept
void build_simple_adjacency()
MapOLhash< Node *, size_t > node_to_id_
size_t size() const noexcept
size_t num_chains() const noexcept
void reorder_adjacency_heavy_first()
bool is_empty() const noexcept
void check_id(const size_t id, const char *where) const
Array< size_t > subtree_size_
const Array< size_t > & pos() const noexcept
std::pair< size_t, size_t > Pair_Key
Node * get_src_node(Arc *arc) const noexcept
Return the source node of arc (only for directed graphs)
constexpr size_t get_num_nodes() const noexcept
Return the total of nodes of graph.
Node * get_tgt_node(Arc *arc) const noexcept
Return the target node of arc (only for directed graphs)
__gmp_expr< typename __gmp_resolve_expr< T, V >::value_type, __gmp_binary_expr< __gmp_expr< T, U >, __gmp_expr< V, W >, __gmp_max_function > > max(const __gmp_expr< T, U > &expr1, const __gmp_expr< V, W > &expr2)
Main namespace for Aleph-w library functions.
and
Check uniqueness with explicit hash + equality functors.
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
std::decay_t< typename HeadC::Item_Type > T
Filtered iterator on all the arcs of a graph.
HLD with path/subtree max queries.
HLD_Max(const GT &g, Node *root, NodeValueFn &&nv, SA sa=SA())
HLD_Max(const GT &g, NodeValueFn &&nv, SA sa=SA())
HLD with path/subtree min queries.
HLD_Min(const GT &g, Node *root, NodeValueFn &&nv, SA sa=SA())
HLD_Min(const GT &g, NodeValueFn &&nv, SA sa=SA())
HLD with path/subtree sum queries.
HLD_Sum(const GT &g, Node *root, NodeValueFn &&nv, SA sa=SA())
HLD_Sum(const GT &g, NodeValueFn &&nv, SA sa=SA())
Open addressing hash map using linear probing.
Data & find(const Key &key)
Find and return the value for a key.
Pair * insert(const Key &key, const Data &data)
Insert a key-value pair (copy semantics).
Pair * search(const Key &key) const noexcept
Search for a key in the map.
Functor returning the maximum of two values.
Functor returning the minimum of two values.
Dynamic array container with automatic resizing.
Dynamic stack implementation based on linked lists.
Dynamic map with open hashing.
Dynamic key-value map based on balanced binary search trees.
Generic graph and digraph implementations.
Segment trees for dynamic range queries with lazy propagation.