
'''simple docstring'''



from manim import *




class     UpperCAmelCase_	(						_SCREAMING_SNAKE_CASE					):






						'''simple docstring'''






						def    _lowercase      (   self ):

												"""simple docstring"""



												_lowerCAmelCase    		=					Rectangle(height=0.5       ,  width=0.5 )
												_lowerCAmelCase    		=					Rectangle(height=0.46       ,  width=0.46 ).set_stroke(width=0 )

												_lowerCAmelCase    		=					[mem.copy() for i in range(6 )]
												_lowerCAmelCase    		=					[mem.copy() for i in range(6 )]
												_lowerCAmelCase    		=					VGroup(*_lowercase ).arrange(_lowercase       ,  buff=0 )
												_lowerCAmelCase    		=					VGroup(*_lowercase ).arrange(_lowercase       ,  buff=0 )
												_lowerCAmelCase    		=					VGroup(_lowercase       ,  _lowercase ).arrange(_lowercase       ,  buff=0 )
												_lowerCAmelCase    		=					Text("""CPU"""       ,  font_size=24 )
												_lowerCAmelCase    		=					Group(_lowercase       ,  _lowercase ).arrange(_lowercase       ,  buff=0.5       ,  aligned_edge=_lowercase )
												cpu.move_to([-2.5, -0.5, 0] )
												self.add(_lowercase )

												_lowerCAmelCase    		=					[mem.copy() for i in range(4 )]
												_lowerCAmelCase    		=					VGroup(*_lowercase ).arrange(_lowercase       ,  buff=0 )
												_lowerCAmelCase    		=					Text("""GPU"""       ,  font_size=24 )
												_lowerCAmelCase    		=					Group(_lowercase       ,  _lowercase ).arrange(_lowercase       ,  buff=0.5       ,  aligned_edge=_lowercase )
												gpu.move_to([-1, -1, 0] )
												self.add(_lowercase )

												_lowerCAmelCase    		=					[mem.copy() for i in range(6 )]
												_lowerCAmelCase    		=					VGroup(*_lowercase ).arrange(_lowercase       ,  buff=0 )

												_lowerCAmelCase    		=					Text("""Model"""       ,  font_size=24 )
												_lowerCAmelCase    		=					Group(_lowercase       ,  _lowercase ).arrange(_lowercase       ,  buff=0.5       ,  aligned_edge=_lowercase )
												model.move_to([3, -1.0, 0] )
												self.add(_lowercase )

												_lowerCAmelCase    		=					[]
												for i, rect in enumerate(_lowercase ):
																		rect.set_stroke(_lowercase )
																		# target = fill.copy().set_fill(YELLOW, opacity=0.7)
																		# target.move_to(rect)
																		# self.add(target)

																		_lowerCAmelCase    		=					Rectangle(height=0.46 / 4       ,  width=0.46 / 3 ).set_stroke(width=0.0 ).set_fill(_lowercase       ,  opacity=0.7 )

																		if i == 0:
																								cpu_target.next_to(cpu_left_col_base[0].get_corner(DOWN + LEFT )       ,  buff=0.02       ,  direction=_lowercase )
																								cpu_target.set_x(cpu_target.get_x() + 0.1 )
																		elif i == 3:
																								cpu_target.next_to(cpu_targs[0]       ,  direction=_lowercase       ,  buff=0.0 )
																		else:
																								cpu_target.next_to(cpu_targs[i - 1]       ,  direction=_lowercase       ,  buff=0.0 )
																		self.add(_lowercase )
																		cpu_targs.append(_lowercase )

												_lowerCAmelCase    		=					[mem.copy() for i in range(6 )]
												_lowerCAmelCase    		=					VGroup(*_lowercase ).arrange(_lowercase       ,  buff=0 )

												_lowerCAmelCase    		=					Text("""Loaded Checkpoint"""       ,  font_size=24 )
												_lowerCAmelCase    		=					Group(_lowercase       ,  _lowercase ).arrange(_lowercase       ,  aligned_edge=_lowercase       ,  buff=0.4 )
												checkpoint.move_to([3, 0.5, 0] )

												_lowerCAmelCase    		=					Square(side_length=2.2 )
												key.move_to([-5, 2, 0] )

												_lowerCAmelCase    		=					MarkupText(
												    F'<b>Key:</b>\n\n<span fgcolor=\'{YELLOW}\'>●</span> Empty Model'       ,  font_size=18       ,  )

												key_text.move_to([-5, 2.4, 0] )

												self.add(_lowercase       ,  _lowercase )

												_lowerCAmelCase    		=					MarkupText(
												    F'<span fgcolor=\'{BLUE}\'>●</span> Checkpoint'       ,  font_size=18       ,  )

												blue_text.next_to(_lowercase       ,  DOWN * 2.4       ,  aligned_edge=key_text.get_left() )

												_lowerCAmelCase    		=					MarkupText(
												    F'Next, a <i><span fgcolor="{BLUE}">second</span></i> model is loaded into memory,\nwith the weights of a <span fgcolor="{BLUE}">single shard</span>.'       ,  font_size=24       ,  )
												step_a.move_to([2, 2, 0] )
												self.play(Write(_lowercase )       ,  Write(_lowercase ) )

												self.play(Write(_lowercase       ,  run_time=1 )       ,  Create(_lowercase       ,  run_time=1 ) )

												_lowerCAmelCase    		=					[]
												_lowerCAmelCase    		=					[]
												for i, rect in enumerate(_lowercase ):
																		_lowerCAmelCase    		=					fill.copy().set_fill(_lowercase       ,  opacity=0.7 )
																		target.move_to(_lowercase )
																		first_animations.append(GrowFromCenter(_lowercase       ,  run_time=1 ) )

																		_lowerCAmelCase    		=					target.copy()
																		cpu_target.generate_target()
																		if i < 5:
																								cpu_target.target.move_to(cpu_left_col_base[i + 1] )
																		else:
																								cpu_target.target.move_to(cpu_right_col_base[i - 5] )
																		second_animations.append(MoveToTarget(_lowercase       ,  run_time=1.5 ) )

												self.play(*_lowercase )
												self.play(*_lowercase )
												self.wait()






'''simple docstring'''

from collections.abc import Sequence
from queue import Queue






class 		a							:


				def __init__(						self       :   List[str]			,							lowercase_       :   str			,							lowercase_       :   List[Any]			,							lowercase_       :   Dict			,							lowercase_       :   int=None			,							lowercase_       :   List[Any]=None   ):
									snake_case_		     =							start
									snake_case_		     =							end
									snake_case_		     =							val
									snake_case_		     =							(start + end) // 2
									snake_case_		     =							left
									snake_case_		     =							right


				def __repr__(						self       :   Any   ):
									return F"SegmentTreeNode(start={self.start}, end={self.end}, val={self.val})"







class 		a							:


				def __init__(						self       :   Any			,							lowercase_       :   Sequence			,							lowercase_       :   List[str]   ):
									snake_case_		     =							collection
									snake_case_		     =							function
									if self.collection:
														snake_case_		     =							self._build_tree(0			,							len(lowercase_   ) - 1   )


				def     A_					(						self       :   Any			,							lowercase_       :   Dict			,							lowercase_       :   Dict   ):
									self._update_tree(self.root			,							lowercase_			,							lowercase_   )


				def     A_					(						self       :   Optional[Any]			,							lowercase_       :   Tuple			,							lowercase_       :   Optional[int]   ):
									return self._query_range(self.root			,							lowercase_			,							lowercase_   )


				def     A_					(						self       :   str			,							lowercase_       :   int			,							lowercase_       :   int   ):
									if start == end:
														return SegmentTreeNode(lowercase_			,							lowercase_			,							self.collection[start]   )
									snake_case_		     =							(start + end) // 2
									snake_case_		     =							self._build_tree(lowercase_			,							lowercase_   )
									snake_case_		     =							self._build_tree(mid + 1			,							lowercase_   )
									return SegmentTreeNode(lowercase_			,							lowercase_			,							self.fn(left.val			,							right.val   )			,							lowercase_			,							lowercase_   )


				def     A_					(						self       :   Optional[int]			,							lowercase_       :   int			,							lowercase_       :   Optional[Any]			,							lowercase_       :   List[str]   ):
									if node.start == i and node.end == i:
														snake_case_		     =							val
														return
									if i <= node.mid:
														self._update_tree(node.left			,							lowercase_			,							lowercase_   )
									else:
														self._update_tree(node.right			,							lowercase_			,							lowercase_   )
									snake_case_		     =							self.fn(node.left.val			,							node.right.val   )


				def     A_					(						self       :   Tuple			,							lowercase_       :   List[Any]			,							lowercase_       :   List[Any]			,							lowercase_       :   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			,							lowercase_			,							lowercase_   )
														else:
																			# range in left child tree and right child tree
																			return self.fn(
																			    self._query_range(node.left			,							lowercase_			,							node.mid   )			,							self._query_range(node.right			,							node.mid + 1			,							lowercase_   )			,							)
									else:
														# range in right child tree
														return self._query_range(node.right			,							lowercase_			,							lowercase_   )


				def     A_					(						self       :   Any   ):
									if self.root is not None:
														snake_case_		     =							Queue()
														queue.put(self.root   )
														while not queue.empty():
																			snake_case_		     =							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)
														a    :							List[Any]										=    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()

