@@ -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 }
0 commit comments