Skip to content

Commit 4d787b8

Browse files
Added k-th ancestor
1 parent d55d809 commit 4d787b8

File tree

1 file changed

+22
-4
lines changed

1 file changed

+22
-4
lines changed

pyrival/graphs/binary_lifting_on_tree.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""
22
Binary lifting technique applied to a tree.
3-
There are three different uses of this implementation
3+
There are four different uses of this implementation
44
55
1. Computing LCA in O(log n) time.
66
@@ -15,14 +15,22 @@
1515
BL = binary_lift(graph, root=0)
1616
print(BL.lca(2, 3)) # prints 1
1717
18-
2. Compute the distance between two nodes in O(log n) time.
18+
2. Compute the k-th ancestor of a node in O(log k) time.
19+
20+
Example:
21+
graph = [[1], [0, 2, 3], [1], [1]]
22+
BL = binary_lift(graph, root=0)
23+
print(BL.kth_ancestor(2, 2)) # prints 0
24+
print(BL.kth_ancestor(2, 3)) # prints -1
25+
26+
3. Compute the distance between two nodes in O(log n) time.
1927
2028
Example:
2129
graph = [[1], [0, 2, 3], [1], [1]]
2230
BL = binary_lift(graph)
2331
print(BL.distance(2, 3)) # prints 2
2432
25-
3. Compute the sum/min/max/... of the weight
33+
4. Compute the sum/min/max/... of the weight
2634
of a path between a pair of nodes in O(log n) time.
2735
2836
res = Path[0]
@@ -87,7 +95,17 @@ def lca(self, a, b):
8795
return a
8896

8997
def distance(self, a, b):
90-
return self.depth[a] + self.depth[b] - 2 * self.depth[self.lca(a,b)]
98+
return self.depth[a] + self.depth[b] - 2 * self.depth[self.lca(a,b)]
99+
100+
def kth_ancestor(self, a, k):
101+
parent = self.parent
102+
d = self.depth[a]
103+
if d < k:
104+
return -1
105+
for i in range(d.bit_length()):
106+
if (d >> i) & 1:
107+
a = parent[i][a]
108+
return a
91109

92110
def __call__(self, a, b):
93111
depth = self.depth

0 commit comments

Comments
 (0)