Skip to content

Commit d3a29c7

Browse files
Hld nits (#94)
* nits * fix other places * remove old test * fix * fix code cov * trying this * fix code cov --------- Co-authored-by: Luke Videckis <[email protected]> Co-authored-by: Cameron Custer <[email protected]>
1 parent 13ba220 commit d3a29c7

File tree

6 files changed

+24
-83
lines changed

6 files changed

+24
-83
lines changed

Cargo.toml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,8 @@ name = "hld_path_composite_yosupo"
125125
path = "examples/graphs/hld_path_composite_yosupo.rs"
126126

127127
[[example]]
128-
name = "hld_jump_on_tree_nodes"
129-
path = "examples/graphs/hld_jump_on_tree_nodes.rs"
130-
131-
[[example]]
132-
name = "hld_jump_on_tree_edges"
133-
path = "examples/graphs/hld_jump_on_tree_edges.rs"
128+
name = "hld_jump_on_path"
129+
path = "examples/graphs/hld_jump_on_path.rs"
134130

135131
[[example]]
136132
name = "hopcroft_karp_yosupo"

examples/graphs/hld_jump_on_tree_edges.rs renamed to examples/graphs/hld_jump_on_path.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ fn main() {
2828
k: usize,
2929
}
3030

31+
assert_eq!(hld.kth_par(u, hld.d[u]), Some(0));
32+
assert_eq!(hld.kth_par(u, hld.d[u] + 1), None);
33+
3134
match hld.kth_on_path(u, v, k) {
3235
Some(w) => {
3336
assert!(k <= hld.dist(u, v));

examples/graphs/hld_jump_on_tree_nodes.rs

Lines changed: 0 additions & 59 deletions
This file was deleted.

src/graphs/hld.rs

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ pub struct HLD {
3333
pub p: Vec<Option<usize>>,
3434
/// time in
3535
pub tin: Vec<usize>,
36+
/// depth
37+
pub d: Vec<usize>,
3638
ord: Vec<usize>,
3739
siz: Vec<usize>,
3840
head: Vec<usize>,
@@ -66,16 +68,19 @@ impl HLD {
6668
}
6769
let mut tin = vec![0; n];
6870
let mut head = vec![0; n];
71+
let mut d = vec![0; n];
6972
let ord = get_dfs_preorder(adj);
7073
for (i, &u) in ord.iter().enumerate() {
7174
tin[u] = i;
7275
for &v in &adj[u] {
76+
d[v] = 1 + d[u];
7377
head[v] = if v == adj[u][0] { head[u] } else { v };
7478
}
7579
}
7680
HLD {
7781
p,
7882
siz,
83+
d,
7984
ord,
8085
tin,
8186
head,
@@ -92,7 +97,7 @@ impl HLD {
9297
let mut u_anc = false;
9398
loop {
9499
if self.tin[u] > self.tin[v] {
95-
std::mem::swap(&mut u, &mut v);
100+
(u, v) = (v, u);
96101
u_anc = !u_anc;
97102
}
98103
if self.head[u] == self.head[v] {
@@ -124,7 +129,7 @@ impl HLD {
124129
pub fn lca(&self, mut u: usize, mut v: usize) -> usize {
125130
loop {
126131
if self.tin[u] > self.tin[v] {
127-
std::mem::swap(&mut u, &mut v);
132+
(u, v) = (v, u);
128133
}
129134
if self.head[u] == self.head[v] {
130135
return u;
@@ -133,16 +138,13 @@ impl HLD {
133138
}
134139
}
135140

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

148150
/// Returns true iff v is in u's subtree
@@ -151,7 +153,7 @@ impl HLD {
151153
/// - Time: O(1)
152154
/// - Space: O(1)
153155
pub fn in_sub(&self, u: usize, v: usize) -> bool {
154-
u == v || self.sub_tree(u).contains(&self.tin[v])
156+
(self.tin[u]..self.tin[u] + self.siz[u]).contains(&self.tin[v])
155157
}
156158

157159
/// Returns true iff w is on the path from u to v
@@ -188,14 +190,13 @@ impl HLD {
188190
/// - Time: O(log n)
189191
/// - Space: O(1)
190192
pub fn kth_on_path(&self, u: usize, v: usize, k: usize) -> Option<usize> {
191-
let mut dst_side = [0; 2];
192-
self.path(u, v, |range, u_anc| dst_side[u_anc as usize] += range.len());
193-
if k < dst_side[1] {
194-
return self.kth_par(u, k);
195-
}
196-
let dst = dst_side[0] + dst_side[1] - !self.vals_edges as usize;
197-
if k <= dst {
198-
self.kth_par(v, dst - k)
193+
let lca_d = self.d[self.lca(u, v)];
194+
let u_lca = self.d[u] - lca_d;
195+
let v_lca = self.d[v] - lca_d;
196+
if k <= u_lca {
197+
self.kth_par(u, k)
198+
} else if k <= u_lca + v_lca {
199+
self.kth_par(v, u_lca + v_lca - k)
199200
} else {
200201
None
201202
}

src/graphs/lca.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ impl LCA {
8484
}
8585
let (mut le, mut ri) = (self.tin[u], self.tin[v]);
8686
if le > ri {
87-
std::mem::swap(&mut le, &mut ri);
87+
(le, ri) = (ri, le);
8888
}
8989
self.p[self.rmq.query(le + 1..ri + 1).1].unwrap()
9090
}

src/strings/suf_ary.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ impl SufAry {
110110
}
111111
let (mut le, mut ri) = (self.sa_inv[i1], self.sa_inv[i2]);
112112
if le > ri {
113-
std::mem::swap(&mut le, &mut ri);
113+
(le, ri) = (ri, le);
114114
}
115115
self.rmq.query(le..ri)
116116
}

0 commit comments

Comments
 (0)