segment_tree_RmQ

ソースコード

from titan_pylib.data_structures.segment_tree.segment_tree_RmQ import SegmentTreeRmQ

view on github

展開済みコード

  1# from titan_pylib.data_structures.segment_tree.segment_tree_RmQ import SegmentTreeRmQ
  2# from titan_pylib.data_structures.segment_tree.segment_tree_interface import (
  3#     SegmentTreeInterface,
  4# )
  5from abc import ABC, abstractmethod
  6from typing import TypeVar, Generic, Union, Iterable, Callable
  7
  8T = TypeVar("T")
  9
 10
 11class SegmentTreeInterface(ABC, Generic[T]):
 12
 13    @abstractmethod
 14    def __init__(self, n_or_a: Union[int, Iterable[T]], op: Callable[[T, T], T], e: T):
 15        raise NotImplementedError
 16
 17    @abstractmethod
 18    def set(self, k: int, v: T) -> None:
 19        raise NotImplementedError
 20
 21    @abstractmethod
 22    def get(self, k: int) -> T:
 23        raise NotImplementedError
 24
 25    @abstractmethod
 26    def prod(self, l: int, r: int) -> T:
 27        raise NotImplementedError
 28
 29    @abstractmethod
 30    def all_prod(self) -> T:
 31        raise NotImplementedError
 32
 33    @abstractmethod
 34    def max_right(self, l: int, f: Callable[[T], bool]) -> int:
 35        raise NotImplementedError
 36
 37    @abstractmethod
 38    def min_left(self, r: int, f: Callable[[T], bool]) -> int:
 39        raise NotImplementedError
 40
 41    @abstractmethod
 42    def tolist(self) -> list[T]:
 43        raise NotImplementedError
 44
 45    @abstractmethod
 46    def __getitem__(self, k: int) -> T:
 47        raise NotImplementedError
 48
 49    @abstractmethod
 50    def __setitem__(self, k: int, v: T) -> None:
 51        raise NotImplementedError
 52
 53    @abstractmethod
 54    def __str__(self):
 55        raise NotImplementedError
 56
 57    @abstractmethod
 58    def __repr__(self):
 59        raise NotImplementedError
 60# from titan_pylib.my_class.supports_less_than import SupportsLessThan
 61from typing import Protocol
 62
 63
 64class SupportsLessThan(Protocol):
 65
 66    def __lt__(self, other) -> bool: ...
 67from typing import Generic, Iterable, TypeVar, Union
 68
 69T = TypeVar("T", bound=SupportsLessThan)
 70
 71
 72class SegmentTreeRmQ(SegmentTreeInterface, Generic[T]):
 73    """RmQ セグ木です。"""
 74
 75    def __init__(self, _n_or_a: Union[int, Iterable[T]], e: T) -> None:
 76        self._e = e
 77        if isinstance(_n_or_a, int):
 78            self._n = _n_or_a
 79            self._log = (self._n - 1).bit_length()
 80            self._size = 1 << self._log
 81            self._data = [self._e] * (self._size << 1)
 82        else:
 83            _n_or_a = list(_n_or_a)
 84            self._n = len(_n_or_a)
 85            self._log = (self._n - 1).bit_length()
 86            self._size = 1 << self._log
 87            _data = [self._e] * (self._size << 1)
 88            _data[self._size : self._size + self._n] = _n_or_a
 89            for i in range(self._size - 1, 0, -1):
 90                _data[i] = (
 91                    _data[i << 1]
 92                    if _data[i << 1] < _data[i << 1 | 1]
 93                    else _data[i << 1 | 1]
 94                )
 95            self._data = _data
 96
 97    def set(self, k: int, v: T) -> None:
 98        if k < 0:
 99            k += self._n
100        assert (
101            0 <= k < self._n
102        ), f"IndexError: {self.__class__.__name__}.set({k}: int, {v}: T), n={self._n}"
103        k += self._size
104        self._data[k] = v
105        for _ in range(self._log):
106            k >>= 1
107            self._data[k] = (
108                self._data[k << 1]
109                if self._data[k << 1] < self._data[k << 1 | 1]
110                else self._data[k << 1 | 1]
111            )
112
113    def get(self, k: int) -> T:
114        if k < 0:
115            k += self._n
116        assert (
117            0 <= k < self._n
118        ), f"IndexError: {self.__class__.__name__}.get({k}: int), n={self._n}"
119        return self._data[k + self._size]
120
121    def prod(self, l: int, r: int) -> T:
122        assert (
123            0 <= l <= r <= self._n
124        ), f"IndexError: {self.__class__.__name__}.prod({l}: int, {r}: int)"
125        l += self._size
126        r += self._size
127        res = self._e
128        while l < r:
129            if l & 1:
130                if res > self._data[l]:
131                    res = self._data[l]
132                l += 1
133            if r & 1:
134                r ^= 1
135                if res > self._data[r]:
136                    res = self._data[r]
137            l >>= 1
138            r >>= 1
139        return res
140
141    def all_prod(self) -> T:
142        return self._data[1]
143
144    def max_right(self, l: int, f=lambda lr: lr):
145        assert (
146            0 <= l <= self._n
147        ), f"IndexError: {self.__class__.__name__}.max_right({l}, f) index out of range"
148        assert f(
149            self._e
150        ), f"{self.__class__.__name__}.max_right({l}, f), f({self._e}) must be true."
151        if l == self._n:
152            return self._n
153        l += self._size
154        s = self._e
155        while True:
156            while l & 1 == 0:
157                l >>= 1
158            if not f(min(s, self._data[l])):
159                while l < self._size:
160                    l <<= 1
161                    if f(min(s, self._data[l])):
162                        if s > self._data[l]:
163                            s = self._data[l]
164                        l += 1
165                return l - self._size
166            s = min(s, self._data[l])
167            l += 1
168            if l & -l == l:
169                break
170        return self._n
171
172    def min_left(self, r: int, f=lambda lr: lr):
173        assert (
174            0 <= r <= self._n
175        ), f"IndexError: {self.__class__.__name__}.min_left({r}, f) index out of range"
176        assert f(
177            self._e
178        ), f"{self.__class__.__name__}.min_left({r}, f), f({self._e}) must be true."
179        if r == 0:
180            return 0
181        r += self._size
182        s = self._e
183        while True:
184            r -= 1
185            while r > 1 and r & 1:
186                r >>= 1
187            if not f(min(self._data[r], s)):
188                while r < self._size:
189                    r = r << 1 | 1
190                    if f(min(self._data[r], s)):
191                        if s > self._data[r]:
192                            s = self._data[r]
193                        r -= 1
194                return r + 1 - self._size
195            s = min(self._data[r], s)
196            if r & -r == r:
197                break
198        return 0
199
200    def tolist(self) -> list[T]:
201        return [self.get(i) for i in range(self._n)]
202
203    def show(self) -> None:
204        print(
205            f"<{self.__class__.__name__}> [\n"
206            + "\n".join(
207                [
208                    "  "
209                    + " ".join(
210                        map(str, [self._data[(1 << i) + j] for j in range(1 << i)])
211                    )
212                    for i in range(self._log + 1)
213                ]
214            )
215            + "\n]"
216        )
217
218    def __getitem__(self, k: int) -> T:
219        assert (
220            -self._n <= k < self._n
221        ), f"IndexError: {self.__class__.__name__}.__getitem__({k}: int), n={self._n}"
222        return self.get(k)
223
224    def __setitem__(self, k: int, v: T):
225        assert (
226            -self._n <= k < self._n
227        ), f"IndexError: {self.__class__.__name__}.__setitem__{k}: int, {v}: T), n={self._n}"
228        self.set(k, v)
229
230    def __str__(self):
231        return "[" + ", ".join(map(str, (self.get(i) for i in range(self._n)))) + "]"
232
233    def __repr__(self):
234        return f"{self.__class__.__name__}({self})"

仕様

class SegmentTreeRmQ(_n_or_a: int | Iterable[T], e: T)[source]

Bases: SegmentTreeInterface, Generic[T]

RmQ セグ木です。

all_prod() T[source]
get(k: int) T[source]
max_right(l: int, f=<function SegmentTreeRmQ.<lambda>>)[source]
min_left(r: int, f=<function SegmentTreeRmQ.<lambda>>)[source]
prod(l: int, r: int) T[source]
set(k: int, v: T) None[source]
show() None[source]
tolist() list[T][source]