Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,8 @@ name = "hld_path_composite_yosupo"
path = "examples/graphs/hld_path_composite_yosupo.rs"

[[example]]
name = "hld_jump_on_tree_nodes"
path = "examples/graphs/hld_jump_on_tree_nodes.rs"

[[example]]
name = "hld_jump_on_tree_edges"
path = "examples/graphs/hld_jump_on_tree_edges.rs"
name = "hld_jump_on_path"
path = "examples/graphs/hld_jump_on_path.rs"

[[example]]
name = "hopcroft_karp_yosupo"
Expand Down
59 changes: 0 additions & 59 deletions examples/graphs/hld_jump_on_tree_nodes.rs

This file was deleted.

32 changes: 16 additions & 16 deletions src/graphs/hld.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub struct HLD {
pub p: Vec<Option<usize>>,
/// time in
pub tin: Vec<usize>,
d: Vec<usize>,
ord: Vec<usize>,
siz: Vec<usize>,
head: Vec<usize>,
Expand Down Expand Up @@ -66,16 +67,19 @@ impl HLD {
}
let mut tin = vec![0; n];
let mut head = vec![0; n];
let mut d = vec![0; n];
let ord = get_dfs_preorder(adj);
for (i, &u) in ord.iter().enumerate() {
tin[u] = i;
for &v in &adj[u] {
d[v] = 1 + d[u];
head[v] = if v == adj[u][0] { head[u] } else { v };
}
}
HLD {
p,
siz,
d,
ord,
tin,
head,
Expand All @@ -92,7 +96,7 @@ impl HLD {
let mut u_anc = false;
loop {
if self.tin[u] > self.tin[v] {
std::mem::swap(&mut u, &mut v);
(u, v) = (v, u);
u_anc = !u_anc;
}
if self.head[u] == self.head[v] {
Expand Down Expand Up @@ -124,7 +128,7 @@ impl HLD {
pub fn lca(&self, mut u: usize, mut v: usize) -> usize {
loop {
if self.tin[u] > self.tin[v] {
std::mem::swap(&mut u, &mut v);
(u, v) = (v, u);
}
if self.head[u] == self.head[v] {
return u;
Expand All @@ -133,16 +137,13 @@ impl HLD {
}
}

/// If !vals_edges, then gets number of nodes on path from u to v
/// If vals_edges, then gets number of edges on path from u to v
/// Gets number of edges on path from u to v
///
/// # Complexity
/// - Time: O(log n)
/// - Space: O(1)
pub fn dist(&self, u: usize, v: usize) -> usize {
let mut dst = 0;
self.path(u, v, |range, _| dst += range.len());
dst
self.d[u] + self.d[v] - 2 * self.d[self.lca(u, v)]
}

/// Returns true iff v is in u's subtree
Expand All @@ -151,7 +152,7 @@ impl HLD {
/// - Time: O(1)
/// - Space: O(1)
pub fn in_sub(&self, u: usize, v: usize) -> bool {
u == v || self.sub_tree(u).contains(&self.tin[v])
(self.tin[u]..self.tin[u] + self.siz[u]).contains(&self.tin[v])
}

/// Returns true iff w is on the path from u to v
Expand Down Expand Up @@ -188,14 +189,13 @@ impl HLD {
/// - Time: O(log n)
/// - Space: O(1)
pub fn kth_on_path(&self, u: usize, v: usize, k: usize) -> Option<usize> {
let mut dst_side = [0; 2];
self.path(u, v, |range, u_anc| dst_side[u_anc as usize] += range.len());
if k < dst_side[1] {
return self.kth_par(u, k);
}
let dst = dst_side[0] + dst_side[1] - !self.vals_edges as usize;
if k <= dst {
self.kth_par(v, dst - k)
let lca_d = self.d[self.lca(u, v)];
let u_lca = self.d[u] - lca_d;
let v_lca = self.d[v] - lca_d;
if k <= u_lca {
self.kth_par(u, k)
} else if k <= u_lca + v_lca {
self.kth_par(v, u_lca + v_lca - k)
} else {
None
}
Expand Down
2 changes: 1 addition & 1 deletion src/graphs/lca.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl LCA {
}
let (mut le, mut ri) = (self.tin[u], self.tin[v]);
if le > ri {
std::mem::swap(&mut le, &mut ri);
(le, ri) = (ri, le);
}
self.p[self.rmq.query(le + 1..ri + 1).1].unwrap()
}
Expand Down
2 changes: 1 addition & 1 deletion src/strings/suf_ary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ impl SufAry {
}
let (mut le, mut ri) = (self.sa_inv[i1], self.sa_inv[i2]);
if le > ri {
std::mem::swap(&mut le, &mut ri);
(le, ri) = (ri, le);
}
self.rmq.query(le..ri)
}
Expand Down
Loading