






from collections.abc import Sequence
from queue import Queue



class   lowerCamelCase				:







		'''simple docstring'''



		def __init__(							self    ,		_UpperCamelCase    ,		_UpperCamelCase    ,		_UpperCamelCase    ,		_UpperCamelCase=None    ,		_UpperCamelCase=None       )     ->							List[str]:
							UpperCAmelCase_   :				Optional[int]						=				start
							UpperCAmelCase_   :				Dict						=				end
							UpperCAmelCase_   :				Tuple						=				val
							UpperCAmelCase_   :				Tuple						=				(start + end) // 2
							UpperCAmelCase_   :				Any						=				left
							UpperCAmelCase_   :				Tuple						=				right



		def __repr__(							self       )     ->							str:
							return f"SegmentTreeNode(start={self.start}, end={self.end}, val={self.val})"





class   lowerCamelCase				:







		'''simple docstring'''



		def __init__(							self    ,		_UpperCamelCase    ,		_UpperCamelCase       )     ->							List[str]:
							UpperCAmelCase_   :				int						=				collection
							UpperCAmelCase_   :				Tuple						=				function
							if self.collection:
												UpperCAmelCase_   :				Optional[int]						=				self._build_tree(0    ,		len(_UpperCamelCase       ) - 1       )



		def  __UpperCAmelCase      (							self    ,		_UpperCamelCase    ,		_UpperCamelCase       )     ->							Union[str, Any]:
							self._update_tree(self.root    ,		_UpperCamelCase    ,		_UpperCamelCase       )



		def  __UpperCAmelCase      (							self    ,		_UpperCamelCase    ,		_UpperCamelCase       )     ->							Optional[int]:
							return self._query_range(self.root    ,		_UpperCamelCase    ,		_UpperCamelCase       )



		def  __UpperCAmelCase      (							self    ,		_UpperCamelCase    ,		_UpperCamelCase       )     ->							Union[str, Any]:
							if start == end:
												return SegmentTreeNode(_UpperCamelCase    ,		_UpperCamelCase    ,		self.collection[start]       )
							UpperCAmelCase_   :				int						=				(start + end) // 2
							UpperCAmelCase_   :				Optional[int]						=				self._build_tree(_UpperCamelCase    ,		_UpperCamelCase       )
							UpperCAmelCase_   :				Any						=				self._build_tree(mid + 1    ,		_UpperCamelCase       )
							return SegmentTreeNode(_UpperCamelCase    ,		_UpperCamelCase    ,		self.fn(left.val    ,		right.val       )    ,		_UpperCamelCase    ,		_UpperCamelCase       )



		def  __UpperCAmelCase      (							self    ,		_UpperCamelCase    ,		_UpperCamelCase    ,		_UpperCamelCase       )     ->							Dict:
							if node.start == i and node.end == i:
												UpperCAmelCase_   :				Dict						=				val
												return
							if i <= node.mid:
												self._update_tree(node.left    ,		_UpperCamelCase    ,		_UpperCamelCase       )
							else:
												self._update_tree(node.right    ,		_UpperCamelCase    ,		_UpperCamelCase       )
							UpperCAmelCase_   :				Tuple						=				self.fn(node.left.val    ,		node.right.val       )



		def  __UpperCAmelCase      (							self    ,		_UpperCamelCase    ,		_UpperCamelCase    ,		_UpperCamelCase       )     ->							Optional[Any]:
							if node.start == i and node.end == j:
												return node.val

							if i <= node.mid:
												if j <= node.mid:
																	# range in left child tree
																	return self._query_range(node.left    ,		_UpperCamelCase    ,		_UpperCamelCase       )
												else:
																	# range in left child tree and right child tree
																	return self.fn(
																	    self._query_range(node.left    ,		_UpperCamelCase    ,		node.mid       )    ,		self._query_range(node.right    ,		node.mid + 1    ,		_UpperCamelCase       )    ,		)
							else:
												# range in right child tree
												return self._query_range(node.right    ,		_UpperCamelCase    ,		_UpperCamelCase       )



		def  __UpperCAmelCase      (							self       )     ->							List[Any]:
							if self.root is not None:
												UpperCAmelCase_   :				int						=				Queue()
												queue.put(self.root       )
												while not queue.empty():
																	UpperCAmelCase_   :				Optional[int]						=				queue.get()
																	yield node

																	if node.left is not None:
																						queue.put(node.left       )

																	if node.right is not None:
																						queue.put(node.right       )


if __name__ == "__main__":
		import operator

		for fn in [operator.add, max, min]:
				print('*' * 50)
				__UpperCAmelCase     							=						SegmentTree([2, 1, 5, 3, 4], fn)
				for node in arr.traverse():
						print(node)
				print()

				arr.update(1, 5)
				for node in arr.traverse():
						print(node)
				print()

				print(arr.query_range(3, 4))  # 7
				print(arr.query_range(2, 2))  # 5
				print(arr.query_range(1, 3))  # 13
				print()














from __future__ import annotations




def 					lowercase__				(					__snake_case   :							list[int]					,	__snake_case   :							int  ):


					'''simple docstring'''


					if len(__snake_case  ) < k or k < 0:
										raise ValueError('Invalid Input'  )
					UpperCAmelCase_   :				int						=						sum(array[:k]  )
					for i in range(len(__snake_case  ) - k  ):
										UpperCAmelCase_   :				List[Any]						=						current_sum - array[i] + array[i + k]
										UpperCAmelCase_   :				List[Any]						=						max(__snake_case					,	__snake_case  )
					return max_sum


if __name__ == "__main__":
		from doctest import testmod
		from random import randint

		testmod()
		__UpperCAmelCase     							=						[randint(-1000, 1000) for i in range(100)]
		__UpperCAmelCase     							=						randint(0, 110)
		print(F'The maximum sum of {k} consecutive elements is {max_sum_in_array(array,k)}')






