# Range query for Largest Sum Contiguous Subarray

Given a number N, and Q queries of two types 1 and 2. Task is to write a code for the given query where, in type-1, given l and r, and task is to print the Largest sum Contiguous Subarray and for type 2, given type, index, and value, update value to Aindex.

Examples :

```Input : a = {-2, -3, 4, -1, -2, 1, 5, -3}
1st query : 1 5 8
2nd query : 2 1 10
3rd query : 1 1 3
Output : Answer to 1st query : 6
Answer to 3rd query : 11
```

Explanation : In the first query, task is to print the largest sum of a contiguous subarray in range 5-8, which consists of {-2, 1, 5, -3}. The largest sum is 6, which is formed by the subarray {1, 5}. In the second query, an update operation is done, which updates a to 10, hence the sequence is {10, -3, 4, -1, -2, 1, 5, -3}. In the third query, task is to print the largest sum of a contiguous subarray in range 1-3, which consists of {10, -3, 4}. The largest sum is 11, which is formed by the subarray {10, -3, 4}.

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

A naive approach is to use Kadane’s algorithm for every type-1 query. The complexity of every type-1 query is O(n). The type-2 query is done in O(1).

Efficient Approach :
An efficient approach is to build a segment tree where each node stores four values(sum, prefixsum, suffixsum, maxsum), and do a range query on it to find the answer to every query. The nodes of segment tree store the four values as mentioned above. The parent will store the merging of left and right child. The parent node stores the value as mentioned below :

parent.sum = left.sum + right.sum
parent.prefixsum = max(left.prefixsum, left.sum + right.prefixsum)
parent.suffixsum = max(right.suffixsum, right.sum + left.suffixsum)
parent.maxsum = max(parent.prefixsum, parent.suffixsum, left.maxsum, right.maxsum, left.suffixsum + right.prefixsum)

Parent node stores the following :

• Parent node’s sum is the summation of left and right child sum.
• Parent node’s prefix sum will be equivalent to maximum of left child’s prefix sum or left child sum + right child prefix sum.
• Parent node’s suffix sum will be equal to right child suffix sum or right child sum + suffix sum of left child
• Parent node’s maxsum will be the maxium of prefixsum or suffix sum of parent or the left or rigth child’s maxsum or the summation of suffixsum of left child and prefixsum of right child.

Representation of Segment trees :
1. Leaf Nodes are the elements of the input array.
2. Each internal node represents some merging of the leaf nodes. The merging may be different for different problems. For this problem, merging is done as given above.

An array representation of tree is used to represent Segment Trees. For each node at index i, the left child is at index 2 * i + 1, right child at 2 * i + 2 and the parent is at (i – 1) / 2.

Construction of Segment Tree from given array :
Start with a segment arr[0 . . . n-1]. and every time divide the current segment into two halves(if it has not yet become a segment of length 1), and then call the same procedure on both halves, and for each such segment, store the values in all the four variables as given in the formulae above.

Update a given value in array and segment Tree :
Start with the complete segment of the array provided to us. Every time divide the array into two halves, ignore the half in which the index to be updated is not present. Keep on ignoring halves at every step until reach the leaf node, where update the value to the given index. Now, merge the updated values according to the given formulae to all the nodes that are present in the path we have traversed.

For every query, move to the left and right halves of the tree. Whenever the given range completely overlaps any halve of a tree, return the Node from that half without traversing further in that region. When a halve of the tree completely lies outside the given range, return INT_MIN. On partial overlapping of range, traverse in left and right halves and return accordingly.

Below is the implementation of the above idea :

## C++

 `// CPP program to find Largest Sum Contiguous ` `// Subarray in a given range with updates ` `#include ` `using` `namespace` `std; ` ` `  `// Structure to store ` `// 4 values that are to be stored ` `// in the nodes ` `struct` `node { ` `    ``int` `sum, prefixsum, suffixsum, maxsum; ` `}; ` ` `  `// array to store the segment tree ` `node tree[4 * 100]; ` ` `  `// function to build the tree ` `void` `build(``int` `arr[], ``int` `low, ``int` `high, ``int` `index) ` `{ ` `    ``// the leaf node ` `    ``if` `(low == high) { ` `        ``tree[index].sum = arr[low]; ` `        ``tree[index].prefixsum = arr[low]; ` `        ``tree[index].suffixsum = arr[low]; ` `        ``tree[index].maxsum = arr[low]; ` `    ``} ` `    ``else` `{ ` `        ``int` `mid = (low + high) / 2; ` `         `  `        ``// left subtree ` `        ``build(arr, low, mid, 2 * index + 1); ` `         `  `        ``// right subtree ` `        ``build(arr, mid + 1, high, 2 * index + 2); ` ` `  `        ``// parent node's sum is the summation  ` `        ``// of left and rigth child ` `        ``tree[index].sum = tree[2 * index + 1].sum +  ` `                          ``tree[2 * index + 2].sum; ` ` `  `        ``// parent node's prefix sum will be equivalent ` `        ``// to maximum of left child's prefix sum or left  ` `        ``// child sum + right child prefix sum. ` `        ``tree[index].prefixsum =  ` `                    ``max(tree[2 * index + 1].prefixsum, ` `                    ``tree[2 * index + 1].sum +  ` `                    ``tree[2 * index + 2].prefixsum); ` ` `  `        ``// parent node's suffix sum will be equal to right ` `        ``// child suffix sum or rigth child sum + suffix  ` `        ``// sum of left child ` `        ``tree[index].suffixsum =  ` `                    ``max(tree[2 * index + 2].suffixsum, ` `                    ``tree[2 * index + 2].sum +  ` `                    ``tree[2 * index + 1].suffixsum); ` ` `  `        ``// maxum will be the maximum of prefix, suffix of ` `        ``// parent or maximum of left child or right child ` `        ``// and summation of left child's suffix and right  ` `        ``// child's prefix. ` `        ``tree[index].maxsum =  ` `                    ``max(tree[index].prefixsum, ` `                    ``max(tree[index].suffixsum, ` `                    ``max(tree[2 * index + 1].maxsum, ` `                    ``max(tree[2 * index + 2].maxsum, ` `                    ``tree[2 * index + 1].suffixsum +  ` `                    ``tree[2 * index + 2].prefixsum)))); ` `    ``} ` `} ` ` `  `// function to update the tree ` `void` `update(``int` `arr[], ``int` `index, ``int` `low, ``int` `high,  ` `            ``int` `idx, ``int` `value) ` `{ ` `    ``// the node to be updated ` `    ``if` `(low == high) { ` `        ``tree[index].sum = value; ` `        ``tree[index].prefixsum = value; ` `        ``tree[index].suffixsum = value; ` `        ``tree[index].maxsum = value; ` `    ``} ` `    ``else` `{ ` ` `  `        ``int` `mid = (low + high) / 2; ` ` `  `        ``// if node to be updated is in left subtree ` `        ``if` `(idx <= mid) ` `            ``update(arr, 2 * index + 1, low, mid, idx, value); ` `         `  `        ``// if node to be updated is in right subtree ` `        ``else` `            ``update(arr, 2 * index + 2, mid + 1,  ` `                   ``high, idx, value); ` ` `  `        ``// parent node's sum is the summation of left  ` `        ``// and rigth child ` `        ``tree[index].sum = tree[2 * index + 1].sum +  ` `                          ``tree[2 * index + 2].sum; ` ` `  `        ``// parent node's prefix sum will be equivalent ` `        ``// to maximum of left child's prefix sum or left  ` `        ``// child sum + right child prefix sum. ` `        ``tree[index].prefixsum =  ` `                    ``max(tree[2 * index + 1].prefixsum, ` `                    ``tree[2 * index + 1].sum +  ` `                    ``tree[2 * index + 2].prefixsum); ` ` `  `        ``// parent node's suffix sum will be equal to right ` `        ``// child suffix sum or rigth child sum + suffix  ` `        ``// sum of left child ` `        ``tree[index].suffixsum =  ` `                    ``max(tree[2 * index + 2].suffixsum, ` `                    ``tree[2 * index + 2].sum +  ` `                    ``tree[2 * index + 1].suffixsum); ` ` `  `        ``// maxum will be the maximum of prefix, suffix of ` `        ``// parent or maximum of left child or right child ` `        ``// and summation of left child's suffix and  ` `        ``// right child's prefix. ` `        ``tree[index].maxsum =  ` `                    ``max(tree[index].prefixsum, ` `                    ``max(tree[index].suffixsum, ` `                    ``max(tree[2 * index + 1].maxsum, ` `                    ``max(tree[2 * index + 2].maxsum, ` `                    ``tree[2 * index + 1].suffixsum +  ` `                    ``tree[2 * index + 2].prefixsum)))); ` `    ``} ` `} ` ` `  `// fucntion to return answer to  every type-1 query ` `node query(``int` `arr[], ``int` `index, ``int` `low,  ` `           ``int` `high, ``int` `l, ``int` `r) ` `{ ` `    ``// initially all the values are INT_MIN ` `    ``node result; ` `    ``result.sum = result.prefixsum =  ` `                 ``result.suffixsum =  ` `                 ``result.maxsum = INT_MIN; ` ` `  `    ``// range does not lies in this subtree ` `    ``if` `(r < low || high < l) ` `        ``return` `result; ` ` `  `    ``// complete overlap of range ` `    ``if` `(l <= low && high <= r) ` `        ``return` `tree[index]; ` ` `  `    ``int` `mid = (low + high) / 2; ` ` `  `    ``// right subtree ` `    ``if` `(l > mid) ` `        ``return` `query(arr, 2 * index + 2,  ` `                     ``mid + 1, high, l, r); ` `         `  `    ``// left subtree     ` `    ``if` `(r <= mid) ` `        ``return` `query(arr, 2 * index + 1,  ` `                     ``low, mid, l, r); ` ` `  `    ``node left = query(arr, 2 * index + 1,  ` `                      ``low, mid, l, r); ` `    ``node right = query(arr, 2 * index + 2,  ` `                        ``mid + 1, high, l, r); ` ` `  `    ``// finding the maximum and returning it ` `    ``result.sum = left.sum + right.sum; ` `    ``result.prefixsum = max(left.prefixsum, left.sum +  ` `                           ``right.prefixsum); ` `                            `  `    ``result.suffixsum = max(right.suffixsum, ` `                       ``right.sum + left.suffixsum); ` `    ``result.maxsum = max(result.prefixsum, ` `                    ``max(result.suffixsum, ` `                    ``max(left.maxsum, ` `                    ``max(right.maxsum, ` `                    ``left.suffixsum + right.prefixsum)))); ` `                     `  `    ``return` `result; ` `} ` ` `  `// Driver Code ` `int` `main() ` `{ ` `    ``int` `a[] = { -2, -3, 4, -1, -2, 1, 5, -3 }; ` `    ``int` `n = ``sizeof``(a) / ``sizeof``(a); ` ` `  `    ``// build the tree ` `    ``build(a, 0, n - 1, 0); ` ` `  `    ``// 1st query type-1 ` `    ``int` `l = 5, r = 8; ` `    ``cout << query(a, 0, 0, n - 1, l - 1, r - 1).maxsum; ` `    ``cout << endl; ` ` `  `    ``// 2nd type-2 query ` `    ``int` `index = 1; ` `    ``int` `value = 10; ` `    ``a[index - 1] = value; ` `    ``update(a, 0, 0, n - 1, index - 1, value); ` ` `  `    ``// 3rd type-1 query ` `    ``l = 1, r = 3; ` `    ``cout << query(a, 0, 0, n - 1, l - 1, r - 1).maxsum; ` ` `  `    ``return` `0; ` `} `

## Java

 `// Java program to find Largest Sum Contiguous ` `// Subarray in a given range with updates ` `class` `GFG  ` `{ ` ` `  `// Structure to store 4 values that are  ` `// to be stored in the nodes ` `static` `class` `node ` `{ ` `    ``int` `sum, prefixsum, suffixsum, maxsum; ` `}; ` ` `  `// array to store the segment tree ` `static` `node[] tree = ``new` `node[``4` `* ``100``]; ` ` `  `// function to build the tree ` `static` `void` `build(``int` `arr[], ``int` `low,  ` `                  ``int` `high, ``int` `index) ` `{ ` `    ``// the leaf node ` `    ``if` `(low == high)  ` `    ``{ ` `        ``tree[index].sum = arr[low]; ` `        ``tree[index].prefixsum = arr[low]; ` `        ``tree[index].suffixsum = arr[low]; ` `        ``tree[index].maxsum = arr[low]; ` `    ``}  ` `    ``else`  `    ``{ ` `        ``int` `mid = (low + high) / ``2``; ` ` `  `        ``// left subtree ` `        ``build(arr, low, mid, ``2` `* index + ``1``); ` ` `  `        ``// right subtree ` `        ``build(arr, mid + ``1``, high, ``2` `* index + ``2``); ` ` `  `        ``// parent node's sum is the summation  ` `        ``// of left and rigth child ` `        ``tree[index].sum = tree[``2` `* index + ``1``].sum +  ` `                          ``tree[``2` `* index + ``2``].sum; ` ` `  `        ``// parent node's prefix sum will be equivalent ` `        ``// to maximum of left child's prefix sum or left  ` `        ``// child sum + right child prefix sum. ` `        ``tree[index].prefixsum = Math.max(tree[``2` `* index + ``1``].prefixsum,  ` `                                         ``tree[``2` `* index + ``1``].sum +  ` `                                         ``tree[``2` `* index + ``2``].prefixsum); ` ` `  `        ``// parent node's suffix sum will be equal to right ` `        ``// child suffix sum or rigth child sum + suffix  ` `        ``// sum of left child ` `        ``tree[index].suffixsum = Math.max(tree[``2` `* index + ``2``].suffixsum,  ` `                                         ``tree[``2` `* index + ``2``].sum + ` `                                         ``tree[``2` `* index + ``1``].suffixsum); ` ` `  `        ``// maxum will be the maximum of prefix, suffix of ` `        ``// parent or maximum of left child or right child ` `        ``// and summation of left child's suffix and right  ` `        ``// child's prefix. ` `        ``tree[index].maxsum = Math.max(tree[index].prefixsum, ` `                             ``Math.max(tree[index].suffixsum,  ` `                             ``Math.max(tree[``2` `* index + ``1``].maxsum,  ` `                             ``Math.max(tree[``2` `* index + ``2``].maxsum, ` `                                      ``tree[``2` `* index + ``1``].suffixsum + ` `                                      ``tree[``2` `* index + ``2``].prefixsum)))); ` `    ``} ` `} ` ` `  `// function to update the tree ` `static` `void` `update(``int` `arr[], ``int` `index, ``int` `low, ` `                   ``int` `high, ``int` `idx, ``int` `value) ` `{ ` `    ``// the node to be updated ` `    ``if` `(low == high) ` `    ``{ ` `        ``tree[index].sum = value; ` `        ``tree[index].prefixsum = value; ` `        ``tree[index].suffixsum = value; ` `        ``tree[index].maxsum = value; ` `    ``}  ` `    ``else` `    ``{ ` `        ``int` `mid = (low + high) / ``2``; ` ` `  `        ``// if node to be updated is in left subtree ` `        ``if` `(idx <= mid) ` `        ``{ ` `            ``update(arr, ``2` `* index + ``1``, low,  ` `                           ``mid, idx, value); ` `        ``}  ` `         `  `        ``// if node to be updated is in right subtree ` `        ``else`  `        ``{ ` `            ``update(arr, ``2` `* index + ``2``, mid + ``1``, ` `                             ``high, idx, value); ` `        ``} ` ` `  `        ``// parent node's sum is the summation of left  ` `        ``// and rigth child ` `        ``tree[index].sum = tree[``2` `* index + ``1``].sum + ` `                          ``tree[``2` `* index + ``2``].sum; ` ` `  `        ``// parent node's prefix sum will be equivalent ` `        ``// to maximum of left child's prefix sum or left  ` `        ``// child sum + right child prefix sum. ` `        ``tree[index].prefixsum = Math.max(tree[``2` `* index + ``1``].prefixsum,  ` `                                         ``tree[``2` `* index + ``1``].sum +  ` `                                         ``tree[``2` `* index + ``2``].prefixsum); ` ` `  `        ``// parent node's suffix sum will be equal to right ` `        ``// child suffix sum or rigth child sum + suffix  ` `        ``// sum of left child ` `        ``tree[index].suffixsum = Math.max(tree[``2` `* index + ``2``].suffixsum,  ` `                                         ``tree[``2` `* index + ``2``].sum +  ` `                                         ``tree[``2` `* index + ``1``].suffixsum); ` ` `  `        ``// maxum will be the maximum of prefix, suffix of ` `        ``// parent or maximum of left child or right child ` `        ``// and summation of left child's suffix and  ` `        ``// right child's prefix. ` `        ``tree[index].maxsum = Math.max(tree[index].prefixsum,  ` `                             ``Math.max(tree[index].suffixsum, ` `                             ``Math.max(tree[``2` `* index + ``1``].maxsum,  ` `                             ``Math.max(tree[``2` `* index + ``2``].maxsum, ` `                                      ``tree[``2` `* index + ``1``].suffixsum +  ` `                                      ``tree[``2` `* index + ``2``].prefixsum)))); ` `    ``} ` `} ` ` `  `// fucntion to return answer to every type-1 query ` `static` `node query(``int` `arr[], ``int` `index,  ` `                  ``int` `low, ``int` `high, ``int` `l, ``int` `r)  ` `{ ` `    ``// initially all the values are Integer.MIN_VALUE ` `    ``node result = ``new` `node(); ` `    ``result.sum = result.prefixsum ` `               ``= result.suffixsum ` `               ``= result.maxsum = Integer.MIN_VALUE; ` ` `  `    ``// range does not lies in this subtree ` `    ``if` `(r < low || high < l) ` `    ``{ ` `        ``return` `result; ` `    ``} ` ` `  `    ``// complete overlap of range ` `    ``if` `(l <= low && high <= r) ` `    ``{ ` `        ``return` `tree[index]; ` `    ``} ` ` `  `    ``int` `mid = (low + high) / ``2``; ` ` `  `    ``// right subtree ` `    ``if` `(l > mid)  ` `    ``{ ` `        ``return` `query(arr, ``2` `* index + ``2``, ` `                     ``mid + ``1``, high, l, r); ` `    ``} ` ` `  `    ``// left subtree  ` `    ``if` `(r <= mid) ` `    ``{ ` `        ``return` `query(arr, ``2` `* index + ``1``, ` `                     ``low, mid, l, r); ` `    ``} ` ` `  `    ``node left = query(arr, ``2` `* index + ``1``, ` `                      ``low, mid, l, r); ` `    ``node right = query(arr, ``2` `* index + ``2``, ` `                       ``mid + ``1``, high, l, r); ` ` `  `    ``// finding the maximum and returning it ` `    ``result.sum = left.sum + right.sum; ` `    ``result.prefixsum = Math.max(left.prefixsum,  ` `                                ``left.sum + right.prefixsum); ` ` `  `    ``result.suffixsum = Math.max(right.suffixsum, ` `                                ``right.sum + left.suffixsum); ` `    ``result.maxsum = Math.max(result.prefixsum, ` `                    ``Math.max(result.suffixsum, ` `                    ``Math.max(left.maxsum, ` `                    ``Math.max(right.maxsum, left.suffixsum + ` `                             ``right.prefixsum)))); ` ` `  `    ``return` `result; ` `} ` ` `  `// Driver Code ` `public` `static` `void` `main(String[] args)  ` `{ ` `    ``int` `a[] = {-``2``, -``3``, ``4``, -``1``, -``2``, ``1``, ``5``, -``3``}; ` `    ``int` `n = a.length; ` `    ``for` `(``int` `i = ``0``; i < ``4` `* ``100``; i++)  ` `    ``{ ` `        ``tree[i] = ``new` `node(); ` `    ``} ` `     `  `    ``// build the tree ` `    ``build(a, ``0``, n - ``1``, ``0``); ` ` `  `    ``// 1st query type-1 ` `    ``int` `l = ``5``, r = ``8``; ` `    ``System.out.print(query(a, ``0``, ``0``, n - ``1``, ` `                     ``l - ``1``, r - ``1``).maxsum); ` `    ``System.out.println(); ` ` `  `    ``// 2nd type-2 query ` `    ``int` `index = ``1``; ` `    ``int` `value = ``10``; ` `    ``a[index - ``1``] = value; ` `    ``update(a, ``0``, ``0``, n - ``1``, index - ``1``, value); ` ` `  `    ``// 3rd type-1 query ` `    ``l = ``1``; ` `    ``r = ``3``; ` `    ``System.out.print(query(a, ``0``, ``0``, n - ``1``, ` `                             ``l - ``1``, r - ``1``).maxsum); ` `} ` `} ` ` `  `// This code is contributed by 29AjayKumar `

Output:

```6
11
```

Time Complexity : O(n log n) for building the tree, O(log n) for every type-1 query, O(1) for type-2 query.

My Personal Notes arrow_drop_up Striver(underscore)79 at Codechef and codeforces D

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.

Improved By : FelipeNoronha, 29AjayKumar