- Choose the aggregate stored for each interval or prefix.
- Build or initialize the structure from the input.
- Apply updates and combine the affected nodes to answer each query.
Code notes
- 172 lines of Python from the credited upstream file abc339_e.py.
- The implementation visibly relies on sequence storage, ordered lookup.
- 1 loop block detected.
Complexity
Count the build once, then multiply the logarithmic update or query path by the number of operations.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
12 3 4import typing5 6 78910def _ceil_pow2(n: int) -> int:11 x = 012 13 while (1 << x) < n:14 x += 115 16 return x17 18 19class SegTree:20 def __init__(21 self,22 op: typing.Callable[[typing.Any, typing.Any], typing.Any],23 e: typing.Any,24 v: typing.Union[int, typing.List[typing.Any]],25 ) -> None:26 self._op = op27 self._e = e28 29 if isinstance(v, int):30 v = [e] * v31 32 self._n = len(v)33 self._log = _ceil_pow2(self._n)34 self._size = 1 << self._log35 self._d = [e] * (2 * self._size)36 37 for i in range(self._n):38 self._d[self._size + i] = v[i]39 for i in range(self._size - 1, 0, -1):40 self._update(i)41 42 def set(self, p: int, x: typing.Any) -> None:43 assert 0 <= p < self._n44 45 p += self._size46 self._d[p] = x47 48 for i in range(1, self._log + 1):49 self._update(p >> i)50 51 def get(self, p: int) -> typing.Any:52 assert 0 <= p < self._n53 54 return self._d[p + self._size]55 56 def prod(self, left: int, right: int) -> typing.Any:57 assert 0 <= left <= right <= self._n58 59 sml = self._e60 smr = self._e61 left += self._size62 right += self._size63 64 while left < right:65 if left & 1:66 sml = self._op(sml, self._d[left])67 left += 168 69 if right & 1:70 right -= 171 smr = self._op(self._d[right], smr)72 73 left >>= 174 right >>= 175 76 return self._op(sml, smr)77 78 def all_prod(self) -> typing.Any:79 return self._d[1]80 81 def max_right(self, left: int, f: typing.Callable[[typing.Any], bool]) -> int:82 assert 0 <= left <= self._n83 assert f(self._e)84 85 if left == self._n:86 return self._n87 88 left += self._size89 sm = self._e90 first = True91 92 while first or (left & -left) != left:93 first = False94 95 while left % 2 == 0:96 left >>= 197 98 if not f(self._op(sm, self._d[left])):99 while left < self._size:100 left *= 2101 102 if f(self._op(sm, self._d[left])):103 sm = self._op(sm, self._d[left])104 left += 1105 return left - self._size106 107 sm = self._op(sm, self._d[left])108 left += 1109 110 return self._n111 112 def min_left(self, right: int, f: typing.Callable[[typing.Any], bool]) -> int:113 assert 0 <= right <= self._n114 assert f(self._e)115 116 if right == 0:117 return 0118 119 right += self._size120 sm = self._e121 122 first = True123 124 while first or (right & -right) != right:125 first = False126 right -= 1127 128 while right > 1 and right % 2:129 right >>= 1130 131 if not f(self._op(self._d[right], sm)):132 while right < self._size:133 right = 2 * right + 1134 if f(self._op(self._d[right], sm)):135 sm = self._op(self._d[right], sm)136 right -= 1137 return right + 1 - self._size138 139 sm = self._op(self._d[right], sm)140 141 return 0142 143 def _update(self, k: int) -> None:144 self._d[k] = self._op(self._d[2 * k], self._d[2 * k + 1])145 146 147def main():148 import sys149 150 input = sys.stdin.readline151 152 n, d = map(int, input().split())153 a = list(map(int, input().split()))154 m = 5 * 10**5 + 10155 156 dp = [0] * m157 st = SegTree(op=max, e=0, v=dp)158 159 for aj in a:160 left = max(0, aj - d)161 right = min(aj + d, m - 1)162 value = st.prod(left, right + 1) + 1163 164 st.set(aj, value)165 166 ans = st.all_prod()167 print(ans)168 169 170if __name__ == "__main__":171 main()172