class Node:
def __init__(self, start, end):
self.start = start
self.end = end
self.mid = (start + end) >> 1
self.min_val = float('inf')
self.max_val = float('-inf')
self.size = 0
self.is_consecutive = False
self.left = None
self.right = None
self.lazy = None
class SegmentTree:
def __init__(self, n):
self.root = self._build(0, n - 1)
def _build(self, start, end):
return Node(start, end)
def _apply_lazy(self, node):
if node.lazy is not None:
node.min_val = node.max_val = node.lazy
node.size = 1
node.is_consecutive = True
if node.start != node.end:
if not node.left:
node.left = self._build(node.start, node.mid)
if not node.right:
node.right = self._build(node.mid + 1, node.end)
node.left.lazy = node.right.lazy = node.lazy
node.lazy = None
def update(self, pos, val, node=None):
node = node or self.root
self._apply_lazy(node)
if pos < node.start or pos > node.end:
return
if node.start == node.end:
node.min_val = node.max_val = val
node.size = 1
node.is_consecutive = True
return
if pos <= node.mid:
if not node.left:
node.left = self._build(node.start, node.mid)
self.update(pos, val, node.left)
else:
if not node.right:
node.right = self._build(node.mid + 1, node.end)
self.update(pos, val, node.right)
left = node.left
right = node.right
node.min_val = min(
left.min_val if left else float('inf'),
right.min_val if right else float('inf')
)
node.max_val = max(
left.max_val if left else float('-inf'),
right.max_val if right else float('-inf')
)
node.size = (
(left.size if left else 0) +
(right.size if right else 0)
)
node.is_consecutive = (
(right.min_val - left.max_val == 1 if left and right else True) and
(left.is_consecutive if left else True) and
(right.is_consecutive if right else True) and
node.size == (node.max_val - node.min_val + 1)
)
def query(self, start, end, node=None):
node = node or self.root
self._apply_lazy(node)
if start > node.end or end < node.start:
return True, float('inf'), float('-inf'), 0
if start <= node.start and end >= node.end:
return (
node.is_consecutive,
node.min_val,
node.max_val,
node.size,
)
left = (
self.query(start, end, node.left)
if node.left else (True, float('inf'), float('-inf'), 0)
)
right = (
self.query(start, end, node.right)
if node.right else (True, float('inf'), float('-inf'), 0)
)
left_cons, left_min, left_max, left_size = left
right_cons, right_min, right_max, right_size = right
is_consecutive = (
left_cons and right_cons and
(right_min - left_max == 1 if left_size and right_size else True) and
(left_size + right_size == right_max - left_min + 1
if left_size and right_size else True)
)
return (
is_consecutive,
min(left_min, right_min),
max(left_max, right_max),
left_size + right_size
)
class Solution:
def resultsArray(self, nums: List[int], k: int) -> List[int]:
n = len(nums)
tree = SegmentTree(n)
for i, num in enumerate(nums):
tree.update(i, num)
result = []
for i in range(n - k + 1):
is_cons, _, max_val, size = tree.query(i, i + k - 1)
result.append(max_val if is_cons and size == k else -1)
return result