class Line: def __init__(self, a, b): self.a = a self.b = b def get(self, x): return self.a * x + self.b class LiChaoNode: def __init__(self, l, r): self.l = l self.r = r self.left = None self.right = None self.line = None class LiChaoTree: def __init__(self, L, R): self.root = LiChaoNode(L, R) def insert_line(self, new_line): stack = [(self.root, new_line)] while stack: node, line = stack.pop() l = node.l r = node.r mid = (l + r) // 2 if node.line is None: node.line = line continue current_line = node.line curr_val_mid = current_line.get(mid) new_val_mid = line.get(mid) if new_val_mid > curr_val_mid: node.line, line = line, current_line curr_val_l = current_line.get(l) new_val_l = line.get(l) curr_val_r = current_line.get(r) new_val_r = line.get(r) if new_val_l > curr_val_l: if not node.left: node.left = LiChaoNode(l, mid) stack.append((node.left, line)) if new_val_r > curr_val_r: if not node.right: node.right = LiChaoNode(mid + 1, r) stack.append((node.right, line)) def query_max(self, x): res = -float('inf') stack = [self.root] while stack: node = stack.pop() if node is None: continue if node.line: res = max(res, node.line.get(x)) mid = (node.l + node.r) // 2 if x <= mid: if node.left: stack.append(node.left) else: if node.right: stack.append(node.right) return res n = int(input()) Q = list(map(int, input().split())) L = -10**5 R = 10**5 tree = LiChaoTree(L, R) tree.insert_line(Line(Q[0], 0)) max_E = -float('inf') for i in range(1, n): x = Q[i] current_max = tree.query_max(x) if current_max > max_E: max_E = current_max tree.insert_line(Line(Q[i], current_max)) print(max_E)