cp_library_rs/graph/
hld.rs1use crate::utils::consts::Infinity;
4
5pub struct HLD {
7 pub N: usize,
9 pub root: usize,
11 pub G: Vec<Vec<usize>>,
13 pub parent: Vec<usize>,
15 pub subtree_size: Vec<usize>,
17 pub in_: Vec<usize>,
19 pub out: Vec<usize>,
21 pub head: Vec<usize>,
23}
24
25impl HLD {
26 pub fn new(N: usize) -> Self {
28 Self {
29 N,
30 root: usize::infinity(),
31 G: vec![vec![]; N],
32 parent: vec![usize::infinity(); N],
33 subtree_size: vec![usize::infinity(); N],
34 in_: vec![usize::infinity(); N],
35 out: vec![usize::infinity(); N],
36 head: vec![usize::infinity(); N],
37 }
38 }
39
40 pub fn add_edge(&mut self, u: usize, v: usize) {
42 self.G[u].push(v);
43 self.G[v].push(u);
44 }
45
46 pub fn decompose(&mut self, root: usize) {
48 self.root = root;
49
50 self.set_heavy_child(usize::infinity(), root);
52
53 self.head[root] = root;
55 self.build_heavy_path(usize::infinity(), root, &mut 0);
56 }
57
58 fn set_heavy_child(&mut self, p: usize, u: usize) {
63 self.parent[u] = p;
64 self.subtree_size[u] = 1;
65
66 for i in 0..self.G[u].len() {
67 let v = self.G[u][i];
68 if v == p {
69 continue;
70 }
71 self.set_heavy_child(u, v);
73
74 self.subtree_size[u] += self.subtree_size[v];
76
77 let v_0 = self.G[u][0];
79 if v_0 == p || self.subtree_size[v] > self.subtree_size[v_0] {
80 self.G[u].swap(i, 0);
81 }
82 }
83 }
84
85 fn build_heavy_path(&mut self, p: usize, u: usize, id: &mut usize) {
87 self.in_[u] = *id;
88 *id += 1;
89
90 for i in 0..self.G[u].len() {
91 let v = self.G[u][i];
92 if v == p {
93 continue;
94 }
95 self.head[v] = if i == 0 {
96 self.head[u]
98 } else {
99 v
100 };
101
102 self.build_heavy_path(u, v, id);
103 }
104
105 self.out[u] = *id;
106 }
107
108 #[inline]
110 pub fn get_id(&self, v: usize) -> usize {
111 self.in_[v]
112 }
113
114 pub fn get_lca(&self, mut u: usize, mut v: usize) -> usize {
116 let mut pu = self.head[u];
117 let mut pv = self.head[v];
118
119 while self.head[u] != self.head[v] {
120 if self.in_[pu] > self.in_[pv] {
121 u = self.parent[pu];
122 pu = self.head[u];
123 } else {
124 v = self.parent[pv];
125 pv = self.head[v];
126 }
127 }
128
129 if self.in_[u] <= self.in_[v] {
130 u
131 } else {
132 v
133 }
134 }
135
136 #[inline]
143 pub fn get_subtree<T, F>(&self, u: usize) -> (usize, usize) {
144 (self.in_[u], self.out[u])
145 }
146
147 pub fn get_path(&self, u: usize, v: usize) -> PathSegment<'_> {
155 PathSegment {
156 hld: self,
157 from: u,
158 to: v,
159 exhasted: false,
160 }
161 }
162}
163
164pub struct PathSegment<'a> {
175 hld: &'a HLD,
176 from: usize,
177 to: usize,
178 exhasted: bool,
179}
180
181impl Iterator for PathSegment<'_> {
182 type Item = (usize, usize, bool, bool);
183
184 fn next(&mut self) -> Option<Self::Item> {
185 let Self {
186 hld,
187 from,
188 to,
189 exhasted,
190 } = *self;
191
192 if exhasted {
193 return None;
194 }
195
196 let HLD {
197 in_, head, parent, ..
198 } = hld;
199
200 Some(if head[from] == head[to] {
201 self.exhasted = true;
202 if in_[from] < in_[to] {
203 (from, to, true, false)
204 } else {
205 (to, from, true, true)
206 }
207 } else if in_[from] < in_[to] {
208 self.to = parent[head[to]];
209 (head[to], to, false, false)
210 } else {
211 self.from = parent[head[from]];
212 (head[from], from, false, true)
213 })
214 }
215}