




"""simple docstring"""




import mpmath  # for roots of unity
import numpy as np






class 					__magic_name__							:






				'''simple docstring'''





				def __init__( self	,				_a=None	,				_a=None				):





							"""simple docstring"""
							# Input as list
							lowerCamelCase       =      list(poly_a or [0]				)[:]
							lowerCamelCase       =      list(poly_b or [0]				)[:]

							# Remove leading zero coefficients
							while self.polyA[-1] == 0:
										self.polyA.pop()
							lowerCamelCase       =      len(self.polyA				)

							while self.polyB[-1] == 0:
										self.polyB.pop()
							lowerCamelCase       =      len(self.polyB				)

							# Add 0 to make lengths equal a power of 2
							lowerCamelCase       =      int(
							    2 ** np.ceil(np.loga(len(self.polyA				) + len(self.polyB				) - 1				)				)				)

							while len(self.polyA				) < self.c_max_length:
										self.polyA.append(0				)
							while len(self.polyB				) < self.c_max_length:
										self.polyB.append(0				)
							# A complex root used for the fourier transform
							lowerCamelCase       =      complex(mpmath.root(x=1	,				n=self.c_max_length	,				k=1				)				)

							# The product
							lowerCamelCase       =      self.__multiply()





				def      _lowerCAmelCase       ( self	,				_a				):





							"""simple docstring"""
							lowerCamelCase       =      [[x] for x in self.polyA] if which == """A""" else [[x] for x in self.polyB]
							# Corner case
							if len(_a				) <= 1:
										return dft[0]
							#
							lowerCamelCase       =      self.c_max_length // 2
							while next_ncol > 0:
										lowerCamelCase       =      [[] for i in range(_a				)]
										lowerCamelCase       =      self.root**next_ncol

										# First half of next step
										lowerCamelCase       =      1
										for j in range(self.c_max_length // (next_ncol * 2)				):
													for i in range(_a				):
																new_dft[i].append(dft[i][j] + current_root * dft[i + next_ncol][j]				)
													current_root *= root
										# Second half of next step
										lowerCamelCase       =      1
										for j in range(self.c_max_length // (next_ncol * 2)				):
													for i in range(_a				):
																new_dft[i].append(dft[i][j] - current_root * dft[i + next_ncol][j]				)
													current_root *= root
										# Update
										lowerCamelCase       =      new_dft
										lowerCamelCase       =      next_ncol // 2
							return dft[0]





				def      _lowerCAmelCase       ( self				):





							"""simple docstring"""
							lowerCamelCase       =      self.__dft("""A"""				)
							lowerCamelCase       =      self.__dft("""B"""				)
							lowerCamelCase       =      [[dft_a[i] * dft_b[i] for i in range(self.c_max_length				)]]
							del dft_a
							del dft_b

							# Corner Case
							if len(inverce_c[0]				) <= 1:
										return inverce_c[0]
							# Inverse DFT
							lowerCamelCase       =      2
							while next_ncol <= self.c_max_length:
										lowerCamelCase       =      [[] for i in range(_a				)]
										lowerCamelCase       =      self.root ** (next_ncol // 2)
										lowerCamelCase       =      1
										# First half of next step
										for j in range(self.c_max_length // next_ncol				):
													for i in range(next_ncol // 2				):
																# Even positions
																new_inverse_c[i].append(
																    (
																        inverce_c[i][j]
																        + inverce_c[i][j + self.c_max_length // next_ncol]
																    )
																    / 2				)
																# Odd positions
																new_inverse_c[i + next_ncol // 2].append(
																    (
																        inverce_c[i][j]
																        - inverce_c[i][j + self.c_max_length // next_ncol]
																    )
																    / (2 * current_root)				)
													current_root *= root
										# Update
										lowerCamelCase       =      new_inverse_c
										next_ncol *= 2
							# Unpack
							lowerCamelCase       =      [round(x[0].real	,				8				) + round(x[0].imag	,				8				) * 1j for x in inverce_c]

							# Remove leading 0's
							while inverce_c[-1] == 0:
										inverce_c.pop()
							return inverce_c





				def __str__( self				):





							"""simple docstring"""
							lowerCamelCase       =      """A = """ + """ + """.join(
							    f'{coef}*x^{i}' for coef, i in enumerate(self.polyA[: self.len_A]				)				)
							lowerCamelCase       =      """B = """ + """ + """.join(
							    f'{coef}*x^{i}' for coef, i in enumerate(self.polyB[: self.len_B]				)				)
							lowerCamelCase       =      """A*B = """ + """ + """.join(
							    f'{coef}*x^{i}' for coef, i in enumerate(self.product				)				)

							return f'{a}\n{b}\n{c}'


# Unit tests
if __name__ == "__main__":
					import doctest

					doctest.testmod()









"""simple docstring"""




from __future__ import annotations

lowerCAmelCase							:    str  							=							[-10, -5, 0, 5, 5.1, 11, 13, 21, 3, 4, -21, -10, -5, -1, 0]
lowerCAmelCase							:    Dict  							=							[-5, 0, 5, 5.1, 11, 13, 21, -1, 4, -1, -10, -5, -1, 0, -1]



def 					a__				(       snake_case__       )		->      list[float]:
			lowerCamelCase       =      []
			lowerCamelCase       =      len(snake_case__       )

			for i in range(snake_case__       ):
						lowerCamelCase       =      -1
						for j in range(i + 1 ,				snake_case__       ):
									if arr[i] < arr[j]:
												lowerCamelCase       =      arr[j]
												break
						result.append(snake_case__       )
			return result



def 					a__				(       snake_case__       )		->      list[float]:
			lowerCamelCase       =      []
			for i, outer in enumerate(snake_case__       ):
						lowerCamelCase       =      -1
						for inner in arr[i + 1 :]:
									if outer < inner:
												lowerCamelCase       =      inner
												break
						result.append(snake_case__       )
			return result



def 					a__				(       snake_case__       )		->      list[float]:
			lowerCamelCase       =      len(snake_case__       )
			lowerCamelCase       =      []
			lowerCamelCase       =      [-1] * arr_size

			for index in reversed(range(snake_case__       )       ):
						if stack:
									while stack[-1] <= arr[index]:
												stack.pop()
												if not stack:
															break
						if stack:
									lowerCamelCase       =      stack[-1]
						stack.append(arr[index]       )
			return result


if __name__ == "__main__":
					from doctest import testmod
					from timeit import timeit

					testmod()
					print(next_greatest_element_slow(arr))
					print(next_greatest_element_fast(arr))
					print(next_greatest_element(arr))

					lowerCAmelCase							:    Dict  							=							(
					    """from __main__ import arr, next_greatest_element_slow, """
					    """next_greatest_element_fast, next_greatest_element"""
					)
					print(
					    """next_greatest_element_slow():""",
					    timeit("""next_greatest_element_slow(arr)""", setup=setup),
					)
					print(
					    """next_greatest_element_fast():""",
					    timeit("""next_greatest_element_fast(arr)""", setup=setup),
					)
					print(
					    """     next_greatest_element():""",
					    timeit("""next_greatest_element(arr)""", setup=setup),
					)



