Source code for titan_pylib.graph.perfect_binary_tree

[docs] 1class PerfectBinaryTree: 2 """1-indexedの完全二分木クラス""" 3 4 def __init__(self) -> None: 5 pass 6
[docs] 7 def par(self, u: int) -> int: 8 """親を返す""" 9 return (u >> 1) if u > 1 else -1
10
[docs] 11 def child_left(self, u: int) -> int: 12 """左の子を返す""" 13 return u << 1
14
[docs] 15 def child_right(self, u: int) -> int: 16 """右の子を返す""" 17 return u << 1 | 1
18
[docs] 19 def children(self, u: int) -> tuple[int, int]: 20 """左右の子をタプルで返す""" 21 return (self.child_left(u), self.child_right(u))
22
[docs] 23 def sibling(self, u: int) -> int: 24 """兄弟を返す""" 25 return u ^ 1
26
[docs] 27 def dep(self, u: int) -> int: 28 """深さを返す / :math:`O(1)`""" 29 return u.bit_length()
30
[docs] 31 def la(self, u: int, k: int) -> int: 32 """``k``個上の祖先を返す 33 k == 0 のとき、u自身を返す 34 """ 35 return u >> k
36
[docs] 37 def lca(self, u: int, v: int) -> int: 38 """lcaを返す""" 39 if self.dep(u) > self.dep(v): 40 u, v = v, u 41 v = self.la(v, self.dep(v) - self.dep(u)) 42 return u >> (u ^ v).bit_length()
43
[docs] 44 def dist(self, u: int, v: int) -> int: 45 """距離を返す""" 46 return self.dep(u) + self.dep(v) - 2*self.dep(self.lca(u, v))
47
[docs] 48 def get_path(self, u: int, v: int) -> list[int]: 49 """uからvへのパスをリストで返す""" 50 def get(x): 51 a = [] 52 while x != lca: 53 a.append(x) 54 x = self.par(x) 55 return a 56 57 lca = self.lca(u, v) 58 return get(u) + [lca] + get(v)[::-1]