Randomized_meldable_heap¶
ソースコード¶
from titan_pylib.data_structures.heap.Randomized_meldable_heap import RandomizedMeldableHeap
展開済みコード¶
1# from titan_pylib.data_structures.heap.Randomized_meldable_heap import RandomizedMeldableHeap
2from typing import TypeVar, Generic, Iterable, Optional
3
4T = TypeVar("T")
5
6
7class RandomizedMeldableHeap(Generic[T]):
8 """併合可能ヒープです。
9
10 [Randomized Meldable Heap](https://trap.jp/post/1050/), traP
11 """
12
13 _x, _y, _z, _w = 123456789, 362436069, 521288629, 88675123
14
15 class Node:
16
17 def __init__(self, key: T) -> None:
18 self.key = key
19 self.left = None
20 self.right = None
21
22 def __init__(self, a: Iterable[T] = []):
23 self.root = None
24 self.size = 0
25 self._build(a)
26
27 def _build(self, a: Iterable[T]) -> None:
28 a = sorted(a)
29 if not a:
30 return
31 n = len(a)
32 pool = [self.Node(e) for e in a]
33 for i in range(len(a)):
34 if i * 2 + 1 < n:
35 pool[i].left = pool[i * 2 + 1]
36 if i * 2 + 2 < n:
37 pool[i].right = pool[i * 2 + 2]
38 self.root = pool[0]
39
40 @classmethod
41 def _randbit(cls) -> int:
42 t = cls._x ^ (cls._x << 11) & 0xFFFFFFFF
43 cls._x, cls._y, cls._z = cls._y, cls._z, cls._w
44 cls._w = (cls._w ^ (cls._w >> 19)) ^ (t ^ (t >> 8)) & 0xFFFFFFFF
45 return cls._w & 1
46
47 @classmethod
48 def _meld(cls, x: Optional[Node], y: Optional[Node]) -> Optional[Node]:
49 if x is None:
50 return y
51 if y is None:
52 return x
53 if x.key > y.key:
54 x, y = y, x
55 if cls._randbit():
56 x.left = cls._meld(x.left, y)
57 else:
58 x.right = cls._meld(x.right, y)
59 return x
60
61 @classmethod
62 def meld(
63 cls, x: "RandomizedMeldableHeap", y: "RandomizedMeldableHeap"
64 ) -> "RandomizedMeldableHeap":
65 new_heap = RandomizedMeldableHeap()
66 new_heap.size = x.size + y.size
67 new_heap.root = cls._meld(x.root, y.root)
68 return new_heap
69
70 def push(self, key: T) -> None:
71 node = RandomizedMeldableHeap.Node(key)
72 self.root = self._meld(self.root, node)
73 self.size += 1
74
75 def pop_min(self) -> T:
76 res = self.root.key
77 self.root = self._meld(self.root.left, self.root.right)
78 return res
79
80 def get_min(self) -> T:
81 return self.root.key
82
83 def tolist(self) -> list[T]:
84 node = self.root
85 stack = []
86 a = []
87 while stack or node:
88 if node:
89 stack.append(node)
90 node = node.left
91 else:
92 node = stack.pop()
93 a.append(node.key)
94 node = node.right
95 a.sort()
96 return a
97
98 def __bool__(self):
99 return self.root is not None
100
101 def __len__(self):
102 return self.size
103
104 def __str__(self):
105 return str(self.tolist())
106
107 def __repr__(self):
108 return f"{self.__class__.__name__}({self})"
仕様¶
- class RandomizedMeldableHeap(a: Iterable[T] = [])[source]¶
Bases:
Generic
[T
]併合可能ヒープです。
[Randomized Meldable Heap](https://trap.jp/post/1050/), traP
- classmethod meld(x: RandomizedMeldableHeap, y: RandomizedMeldableHeap) RandomizedMeldableHeap [source]¶