# Function to build the segment tree class Node: def __init__(self): self.sum = 0 self.prefix = 0 # Function to build the segment tree def build(arr, ind, start, end, tree): # if there is only one element if start == end: tree[ind].sum = arr[start] tree[ind].prefix = arr[start] else: mid = (start + end) // 2 # If there are more than one elements, build(arr, 2 * ind + 1, start, mid, tree) build(arr, 2 * ind + 2, mid + 1, end, tree) # adds the sum and stores in the tree[ind].sum = tree[2 * ind + 1].sum + tree[2 * ind + 2].sum # stores the max of prefix-sum either tree[ind].prefix = max(tree[2 * ind + 1].prefix, tree[2 * ind + 1].sum + tree[2 * ind + 2].prefix) # Function to do the range query in the # segment tree for the maximum prefix sum def query(ind, start, end, l, r, tree): result = Node() result.sum = result.prefix = -1 # If segment of this node is outside the given # range, then return the minimum value. if start > r or end < l: return result # If segment of this node is a part of given # range, then return the node of the segment if start >= l and end <= r: return tree[ind] mid = (start + end) // 2 # if left segment of this node falls out of # range, then recur in the right side of the tree if l > mid: return query(2 * ind + 2, mid + 1, end, l, r, tree) # if right segment of this node falls out of # range, then recur in the left side of the tree if r <= mid: return query(2 * ind + 1, start, mid, l, r, tree) left = query(2 * ind + 1, start, mid, l, r, tree) right = query(2 * ind + 2, mid + 1, end, l, r, tree) # adds the sum of the left and right segment result.sum = left.sum + right.sum # stores the max of prefix-sum result.prefix = max(left.prefix, left.sum + right.prefix) # returns the value return result # Function to return the maximum prefix sum for each query def maxPrefixes(arr, leftIndex, rightIndex): n = len(arr) # to store the segment tree tree = [Node() for _ in range(4 * n)] # build the segment tree build(arr, 0, 0, n - 1, tree) q = len(leftIndex) # to store the results res = [] for i in range(q): l = leftIndex[i] r = rightIndex[i] # query the segment tree result = query(0, 0, n - 1, l, r, tree) # store the result res.append(result.prefix) return res if __name__ == "__main__": arr = [1, -2, 3, 4, -5] leftIndex = [0, 2, 1] rightIndex = [4, 3, 3] res = maxPrefixes(arr, leftIndex, rightIndex) print(" ".join(map(str, res)))