range_queries::heavy_light_decomposition::HLD< X > Class Template Reference

The Heavy-Light Decomposition class. More...

Inheritance diagram for range_queries::heavy_light_decomposition::HLD< X >:
[legend]
Collaboration diagram for range_queries::heavy_light_decomposition::HLD< X >:
[legend]

## Public Member Functions

| HLD (int nodes)
| Class parameterized constructor. Resizes the and initilizes the data members. More...
void | init ()
| This function must be called after the tree adjacency list and node values are populated The function initializes the required parametes, and populates the segment tree. More...
void | update (int node, X val)
| This function updates the value at node with val. More...
X | query (int a, int b)
| This function returns the sum of node values in the simple path from from node_1 to node_2. More...
Public Member Functions inherited from range_queries::heavy_light_decomposition::Tree< X >
| Tree (int nodes)
| Class parameterized constructor, resizes the and initializes the data members. More...
void | add_edge (const int u, const int v)
| Adds an undirected edge from node u to node v in the tree. More...
void | change_root (int new_root)
| Set the root for the tree. More...
void | set_node_val (const std::vector< X > &node_val)
| Set the values for all the nodes. More...
void | init ()
| This function must be called after the tree adjacency list and node values are populated The function initializes the required parameters, and populates the segment tree. More...
void | lift (int *const p, int dist)
| The function lifts a node, k units up the tree. The lifting is done in place, and the result is stored in the address pointed by p. More...
int | kth_ancestor (int p, const int &dist)
| The function returns the kth ancestor of a node. More...
int | lca (int a, int b)
| The function returns the least common ancestor of two nodes. More...

## Private Member Functions

void | dfs_hc (int u, int p=-1)
| Utility function to assign heavy child to each node (-1 for a leaf node) More...
void | dfs_par (int u, int p=-1)
| Utility function to assign highest parent that can be reached though heavy chains. More...
void | dfs_labels (int u, int p=-1)
| Utility function to lable the nodes so that heavy chains have a contigous lable. More...
X | chain_query (int a, int b)
| Utility function to break down a path query into two chain queries. More...

## Private Attributes

int | label
| utility member to assign labels in dfs_labels()
std::vector< int > | h_label
| stores the label of a node
std::vector< int > | h_heavychlid
| stores the heavy child of a node
std::vector< int > | h_parent
| stores the top of the heavy chain from a node

## Detailed Description

### template<typename X>
class range_queries::heavy_light_decomposition::HLD< X >

The Heavy-Light Decomposition class.

Template Parameters

  the | data type of the values stored in the tree nodes

## Constructor & Destructor Documentation

## HLD()

template<typename X >

range_queries::heavy_light_decomposition::HLD< X >::HLD | ( | int | nodes | ) |

inlineexplicit

Class parameterized constructor. Resizes the and initilizes the data members.

Parameters

  nodes | the total number of nodes in the tree

: Tree<X>(nodes), SG<X>(nodes) {
/* Initialization and resize vectors */
label = 0;
h_label.assign(Tree<X>::t_nodes, -1);
h_heavychlid.assign(Tree<X>::t_nodes, -1);
h_parent.resize(Tree<X>::t_nodes);
iota(h_parent.begin(), h_parent.end(), 0);
}
std::vector::assign
T assign(T... args)
std::vector::begin
T begin(T... args)
range_queries::heavy_light_decomposition::HLD::h_parent
std::vector< int > h_parent
stores the top of the heavy chain from a node
Definition: heavy_light_decomposition.cpp:341
range_queries::heavy_light_decomposition::HLD::label
int label
utility member to assign labels in dfs_labels()
Definition: heavy_light_decomposition.cpp:338
range_queries::heavy_light_decomposition::HLD::h_heavychlid
std::vector< int > h_heavychlid
stores the heavy child of a node
Definition: heavy_light_decomposition.cpp:340
range_queries::heavy_light_decomposition::HLD::h_label
std::vector< int > h_label
stores the label of a node
Definition: heavy_light_decomposition.cpp:339
range_queries::heavy_light_decomposition::Tree::t_nodes
const int t_nodes
number of nodes
Definition: heavy_light_decomposition.cpp:84
std::vector::end
T end(T... args)
std::iota
T iota(T... args)
std::vector::resize
T resize(T... args)

## Member Function Documentation

## chain_query()

template<typename X >

X range_queries::heavy_light_decomposition::HLD< X >::chain_query | ( | int | a,
|  | int | b
| ) |  |

inlineprivate

Utility function to break down a path query into two chain queries.

Parameters

  a | node where the path starts
  b | node where the path ends a and b must belong to a single root to leaf chain

Returns
  the sum of ndoe values in the simple path from a to b

{
X ret = SG<X>::sret_init;
if (Tree<X>::t_depth[a] < Tree<X>::t_depth[b]) {
std::swap(a, b);
}
while (Tree<X>::t_depth[a] >= Tree<X>::t_depth[b]) {
int l = h_label[h_parent[a]];
int r = h_label[a];
if (Tree<X>::t_depth[h_parent[a]] < Tree<X>::t_depth[b]) {
l += Tree<X>::t_depth[b] - Tree<X>::t_depth[h_parent[a]];
}
ret = SG<X>::combine(ret, SG<X>::query(l, r));
a = Tree<X>::t_par[h_parent[a]][0];
if (a == -1) {
break;
}
}
return ret;
}
range_queries::heavy_light_decomposition::SG::query
X query(int l, int r)
Make a range query from node label l to node label r.
Definition: heavy_light_decomposition.cpp:305
range_queries::heavy_light_decomposition::SG::combine
X combine(X lhs, X rhs)
Function that specifies the type of operation involved when segments are combined.
Definition: heavy_light_decomposition.cpp:274
range_queries::heavy_light_decomposition::SG::sret_init
X sret_init
inital query return value
Definition: heavy_light_decomposition.cpp:264
range_queries::heavy_light_decomposition::Tree::t_depth
std::vector< int > t_depth
a vector to store the depth of a node,
Definition: heavy_light_decomposition.cpp:88
range_queries::heavy_light_decomposition::Tree::t_par
std::vector< std::vector< int > > t_par
a matrix to store every node's 2^kth parent
Definition: heavy_light_decomposition.cpp:87
std::swap
T swap(T... args)
Here is the call graph for this function:

## dfs_hc()

template<typename X >

void range_queries::heavy_light_decomposition::HLD< X >::dfs_hc | ( | int | u,
|  | int | p = `-1`
| ) |  |

inlineprivate

Utility function to assign heavy child to each node (-1 for a leaf node)

Parameters

  u | current dfs node
  p | the parent of node u

Returns
  void

{
int hc_size = -1, hc_id = -1;
for (const int &v : Tree<X>::t_adj[u]) {
if (v ^ p) {
dfs_hc(v, u);
if (Tree<X>::t_size[v] > hc_size) {
hc_size = Tree<X>::t_size[v];
hc_id = v;
}
}
}
h_heavychlid[u] = hc_id;
}
range_queries::heavy_light_decomposition::HLD::dfs_hc
void dfs_hc(int u, int p=-1)
Utility function to assign heavy child to each node (-1 for a leaf node)
Definition: heavy_light_decomposition.cpp:350
range_queries::heavy_light_decomposition::Tree::t_adj
std::vector< std::list< int > > t_adj
an adjacency list to stores the tree edges
Definition: heavy_light_decomposition.cpp:83
range_queries::heavy_light_decomposition::Tree::t_size
std::vector< int > t_size
a vector to store the subtree size rooted at node
Definition: heavy_light_decomposition.cpp:89

## dfs_labels()

template<typename X >

void range_queries::heavy_light_decomposition::HLD< X >::dfs_labels | ( | int | u,
|  | int | p = `-1`
| ) |  |

inlineprivate

Utility function to lable the nodes so that heavy chains have a contigous lable.

Parameters

  u | current dfs node
  p | the parent of node u

Returns
  void

{
h_label[u] = label++;
if (h_heavychlid[u] != -1) {
dfs_labels(h_heavychlid[u], u);
}
for (const int &v : Tree<X>::t_adj[u]) {
if (v ^ p and v ^ h_heavychlid[u]) {
dfs_labels(v, u);
}
}
}
range_queries::heavy_light_decomposition::HLD::dfs_labels
void dfs_labels(int u, int p=-1)
Utility function to lable the nodes so that heavy chains have a contigous lable.
Definition: heavy_light_decomposition.cpp:390

## dfs_par()

template<typename X >

void range_queries::heavy_light_decomposition::HLD< X >::dfs_par | ( | int | u,
|  | int | p = `-1`
| ) |  |

inlineprivate

Utility function to assign highest parent that can be reached though heavy chains.

Parameters

  u | current dfs node
  p | the parent of node u

Returns
  void

{
if (h_heavychlid[u] != -1) {
h_parent[h_heavychlid[u]] = h_parent[u];
dfs_par(h_heavychlid[u], u);
}
for (const int &v : Tree<X>::t_adj[u]) {
if (v ^ p and v ^ h_heavychlid[u]) {
dfs_par(v, u);
}
}
}
range_queries::heavy_light_decomposition::HLD::dfs_par
void dfs_par(int u, int p=-1)
Utility function to assign highest parent that can be reached though heavy chains.
Definition: heavy_light_decomposition.cpp:371

## init()

template<typename X >

void range_queries::heavy_light_decomposition::HLD< X >::init | ( |  | ) |

inline

This function must be called after the tree adjacency list and node values are populated The function initializes the required parametes, and populates the segment tree.

Returns
  void

{
Tree<X>::init();
// Fill the heavy child, greatest parent, and labels
label = 0;
dfs_hc(Tree<X>::t_root);
dfs_par(Tree<X>::t_root);
dfs_labels(Tree<X>::t_root);
// Segment Tree Initialization
for (int i = 0; i < Tree<X>::t_nodes; i++) {
SG<X>::s_tree[h_label[i] + Tree<X>::t_nodes] = Tree<X>::t_val[i];
}
for (int i = Tree<X>::t_nodes - 1; i > 0; i--) {
SG<X>::s_tree[i] =
SG<X>::combine(SG<X>::s_tree[i << 1], SG<X>::s_tree[i << 1 | 1]);
}
}
range_queries::heavy_light_decomposition::SG::s_tree
std::vector< X > s_tree
Everything here is private, and can only be accessed through the methods, in the derived class (HLD)
Definition: heavy_light_decomposition.cpp:262
range_queries::heavy_light_decomposition::Tree::t_val
std::vector< X > t_val
values of nodes
Definition: heavy_light_decomposition.cpp:92
range_queries::heavy_light_decomposition::Tree::t_root
int t_root
the root of the tree
Definition: heavy_light_decomposition.cpp:91
range_queries::heavy_light_decomposition::Tree::init
void init()
This function must be called after the tree adjacency list and node values are populated The function...
Definition: heavy_light_decomposition.cpp:186
Here is the call graph for this function:

## query()

template<typename X >

X range_queries::heavy_light_decomposition::HLD< X >::query | ( | int | a,
|  | int | b
| ) |  |

inline

This function returns the sum of node values in the simple path from from node_1 to node_2.

Parameters

  a | the node where the simple path starts
  b | the node where the simple path ends (parameters are interchangeable, i.e., the function is commutative)

Returns
  the sum of node values in the simple path from a to b

{
int lc = Tree<X>::lca(a, b);
X ret = SG<X>::sret_init;
assert(lc != -1);
ret += chain_query(a, lc);
ret += chain_query(b, lc);
return ret - Tree<X>::t_val[lc];
}
range_queries::heavy_light_decomposition::HLD::chain_query
X chain_query(int a, int b)
Utility function to break down a path query into two chain queries.
Definition: heavy_light_decomposition.cpp:409
range_queries::heavy_light_decomposition::Tree::lca
int lca(int a, int b)
The function returns the least common ancestor of two nodes.
Definition: heavy_light_decomposition.cpp:229
Here is the call graph for this function:

## update()

template<typename X >

void range_queries::heavy_light_decomposition::HLD< X >::update | ( | int | node,
|  | X | val
| ) |  |

inline

This function updates the value at node with val.

Parameters

  node | the node where the update is done
  val | the value that is being updated

Returns
  void

{
X diff = val - Tree<X>::t_val[node];
SG<X>::update(h_label[node], diff);
Tree<X>::t_val[node] = val;
}
range_queries::heavy_light_decomposition::SG::update
void update(int p, X v)
Update the value at a node.
Definition: heavy_light_decomposition.cpp:293
node
struct list node
node
Definition: avltree.cpp:13
Here is the call graph for this function:

The documentation for this class was generated from the following file:

- range_queries/heavy_light_decomposition.cpp