competitive/tree/
level_ancestor.rs1use super::UndirectedSparseGraph;
2
3pub struct LevelAncestor {
4 parent: Vec<usize>,
5 depth: Vec<usize>,
6 start: Vec<usize>,
7 index: Vec<usize>,
8 ladder: Vec<usize>,
9}
10
11impl UndirectedSparseGraph {
12 pub fn level_ancestor(&self, root: usize) -> LevelAncestor {
13 let n = self.vertices_size();
14 let (order, parent) = self.tree_order(root);
15 let mut depth = vec![0; n];
16 for &u in order.iter().skip(1) {
17 depth[u] = depth[parent[u]] + 1;
18 }
19 let mut height = vec![1; n];
20 let mut heavy = vec![n; n];
21 for &u in order.iter().skip(1).rev() {
22 let p = parent[u];
23 if heavy[p] == n || height[heavy[p]] < height[u] {
24 heavy[p] = u;
25 }
26 height[p] = height[p].max(height[u] + 1);
27 }
28
29 let mut start = vec![0; n];
30 let mut index = vec![0; n];
31 let mut ladder = Vec::with_capacity(2 * n);
32 for &head in &order {
33 if head != root && heavy[parent[head]] == head {
34 continue;
35 }
36 let extension = height[head].min(depth[head]);
37 let offset = ladder.len();
38 ladder.resize(offset + extension + height[head], n);
39 let mut u = head;
40 for i in (0..extension).rev() {
41 u = parent[u];
42 ladder[offset + i] = u;
43 }
44 let mut u = head;
45 for i in extension..extension + height[head] {
46 ladder[offset + i] = u;
47 start[u] = offset;
48 index[u] = offset + i;
49 u = heavy[u];
50 }
51 }
52
53 LevelAncestor {
54 parent,
55 depth,
56 start,
57 index,
58 ladder,
59 }
60 }
61
62 pub fn level_ancestor_batch(
63 &self,
64 root: usize,
65 queries: impl IntoIterator<Item = (usize, usize)>,
66 ) -> Vec<Option<usize>> {
67 let n = self.vertices_size();
68 let mut start = vec![0; n + 1];
69 let queries: Vec<(usize, usize)> = queries.into_iter().collect();
70 for &(u, _) in &queries {
71 start[u] += 1;
72 }
73 for d in 0..n {
74 start[d + 1] += start[d];
75 }
76 let qsize = queries.len();
77 let mut batch = vec![(0, 0); qsize];
78 for (i, &(u, k)) in queries.iter().enumerate() {
79 start[u] -= 1;
80 batch[start[u]] = (k, i);
81 }
82 let (order, parent) = self.tree_order(root);
83 let mut path = Vec::with_capacity(n);
84 let mut results = vec![None; qsize];
85 for u in order {
86 while path.last().is_some_and(|&v| v != parent[u]) {
87 path.pop();
88 }
89 path.push(u);
90 for &(k, qi) in &batch[start[u]..start[u + 1]] {
91 let depth = path.len() - 1;
92 if k <= depth {
93 results[qi] = Some(path[depth - k]);
94 }
95 }
96 }
97 results
98 }
99}
100
101impl LevelAncestor {
102 #[inline]
103 pub fn la(&self, mut u: usize, mut k: usize) -> Option<usize> {
104 if self.depth[u] < k {
105 return None;
106 }
107 loop {
108 let start = self.start[u];
109 let index = self.index[u];
110 if k <= index - start {
111 return Some(self.ladder[index - k]);
112 }
113 k -= index - start + 1;
114 u = self.parent[self.ladder[start]];
115 }
116 }
117
118 #[inline]
119 pub fn depth(&self, u: usize) -> usize {
120 self.depth[u]
121 }
122}
123
124#[cfg(test)]
125mod tests {
126 use crate::{graph::Graph, tools::Xorshift, tree::MixedTree};
127
128 #[test]
129 fn test_level_ancestor() {
130 let mut rng = Xorshift::default();
131 for _ in 0..500 {
132 let n = rng.random(1..=200);
133 let tree = rng.random(MixedTree(n));
134 let root = rng.random(0..n);
135 let la = tree.level_ancestor(root);
136 let mut parent = vec![None; n];
137 let mut stack = vec![(root, None)];
138 while let Some((u, p)) = stack.pop() {
139 parent[u] = p;
140 for a in tree.neighbors(u) {
141 if Some(a.to) != p {
142 stack.push((a.to, Some(u)));
143 }
144 }
145 }
146 let mut queries = vec![];
147 let mut results = vec![];
148 for u in 0..n {
149 let mut v = Some(u);
150 for d in 0..=n {
151 assert_eq!(la.la(u, d), v);
152 queries.push((u, d));
153 results.push(v);
154 v = v.and_then(|x| parent[x]);
155 }
156 }
157 assert_eq!(tree.level_ancestor_batch(root, queries), results);
158 }
159 }
160}