# Queries for greatest pair sum in the given index range using Segment Tree

Given an array arr[] containing N integers and an array Q[] representing the range [L, R], the task is to find the greatest pair sum value in the range [L, R] where 0 ≤ L ≤ R ≤ N – 1.

Examples:

Input: arr[] = {1, 3, 2, 7, 9, 11}, Q[] = {1, 4}
Output: 16
Explanation:
The greatest pair sum in range 1 to 4 is 7 + 9 = 16.

Input: arr[] = {0, 1, 2, 3, 4, 5, 6, 7}, Q[] = {5, 7}
Output: 13
Explanation:
The greatest pair sum in range 5 to 7 is 6 + 7 = 13.

Naive Approach: The naive approach for this problem is to run a loop from [L, R] and find the two greatest elements in the given range. Their sum is always the greatest pair sum in the given index range. The time complexity of this approach is O(N) for every query.

Efficient Approach: The idea is to use a Segment tree in order to perform some preprocessing and find the value for every query in logarithmic time.

Representation of the Segment tree:

1. Leaf Nodes are the elements of the input array.
2. Each internal node contains the greatest pair sum as well as the maximum element of all leaves under it.

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

Construction of Segment Tree from given array:

• We start with a segment from the given array arr[].
• At each step, we divide the current segment into two halves(if it has not yet become a segment of length 1).
• The above step is performed recursively again on the obtained halves of the array.
• For every segment, we store the maximum value as well as the greatest pair sum in a segment tree node.
• The maximum pair sum and the maximum value for every node can be found as:

Maximum Pair Sum-> maximum( Left child’s maximum pair sum, Right child’s maximum pair sum, Left child’s maximum value + Right child’s maximum value)

Maximum Value -> maximum(Left child’s maximum value, Right child’s maximum value )

Below is the implementation of the above approach:

 `// C++ program for range greatest ` `// pair sum query using segment tree ` ` `  `#include ` `using` `namespace` `std; ` ` `  `// Defining the node ` `struct` `node { ` `    ``int` `maxVal, greatestPSum; ` `} st[100009]; ` ` `  `// A utility function ` `node util(node x, node y) ` `{ ` `    ``node ans; ` ` `  `    ``// Find the maximum pair sum ` `    ``ans.greatestPSum ` `        ``= max(x.maxVal + y.maxVal, ` `              ``max(x.greatestPSum, ` `                  ``y.greatestPSum)); ` `    ``// Find the maximum value ` `    ``ans.maxVal = max(x.maxVal, y.maxVal); ` `    ``return` `ans; ` `} ` ` `  `// A utility function to get the ` `// middle index from corner indexes. ` `int` `getMid(``int` `s, ``int` `e) ` `{ ` `    ``return` `s + (e - s) / 2; ` `} ` ` `  `/* A recursive function to get the ` `greatest pair sum value in a given range  ` `of array indexes. Here: ` ` `  `index --> Index of current node in the  ` `          ``segment tree. Initially 0 is  ` `          ``passed as root is always at index 0  ` `ss & se --> Starting and ending indexes  ` `            ``of the segment represented  ` `            ``by current node, i.e., st[index]  ` `qs & qe --> Starting and ending indexes ` `            ``of query range */` `node query(``int` `ss, ``int` `se, ``int` `qs, ` `           ``int` `qe, ``int` `index) ` `{ ` `    ``// If segment of this node is a part ` `    ``// of given range, then return ` `    ``// the min of the segment ` `    ``if` `(qs <= ss && qe >= se) ` `        ``return` `st[index]; ` ` `  `    ``node temp; ` `    ``temp.maxVal = -1, ` `    ``temp.greatestPSum = -1; ` ` `  `    ``// If segment of this node ` `    ``// is outside the given range ` `    ``if` `(se < qs || ss > qe) ` `        ``return` `temp; ` ` `  `    ``// If a part of this segment ` `    ``// overlaps with the given range ` `    ``int` `mid = getMid(ss, se); ` `    ``return` `util(query(ss, mid, qs, ` `                      ``qe, 2 * index + 1), ` ` `  `                ``query(mid + 1, se, qs, ` `                      ``qe, 2 * index + 2)); ` `} ` ` `  `// Function to return the greatest pair ` `// sum in the range from index ` `// qs (query start) to qe (query end) ` `node checkQuery(``int` `n, ``int` `qs, ``int` `qe) ` `{ ` `    ``node temp; ` `    ``temp.maxVal = -1, temp.greatestPSum = -1; ` ` `  `    ``// Check for erroneous input values ` `    ``if` `(qs < 0 || qe > n - 1 || qs > qe) { ` `        ``cout << ``"Invalid Input"``; ` `        ``return` `temp; ` `    ``} ` ` `  `    ``return` `query(0, n - 1, qs, qe, 0); ` `} ` ` `  `// A recursive function that constructs ` `// Segment Tree for array[ss..se]. ` `// si is index of current node in segment tree ` `node constructST(``int` `arr[], ``int` `ss, ` `                 ``int` `se, ``int` `si) ` `{ ` `    ``// If there is one element in array, ` `    ``// store it in current node of ` `    ``// segment tree and return ` `    ``if` `(ss == se) { ` `        ``st[si].maxVal = arr[ss]; ` `        ``st[si].greatestPSum = 0; ` `        ``return` `st[si]; ` `    ``} ` ` `  `    ``// If there are more than one elements, ` `    ``// then recur for left and right subtrees ` `    ``int` `mid = getMid(ss, se); ` `    ``st[si] = util(constructST(arr, ss, mid, ` `                              ``si * 2 + 1), ` ` `  `                  ``constructST(arr, mid + 1, se, ` `                              ``si * 2 + 2)); ` `    ``return` `st[si]; ` `} ` ` `  `// Utility function to find the ` `// greatest pair sum for the given ` `// queries ` `void` `operation(``int` `arr[], ``int` `n, ` `               ``int` `qs, ``int` `qe) ` `{ ` `    ``// Build segment tree from given array ` `    ``constructST(arr, 0, n - 1, 0); ` ` `  `    ``node ans = checkQuery(n, qs, qe); ` ` `  `    ``// Print minimum value in arr[qs..qe] ` `    ``cout << ans.greatestPSum << endl; ` `} ` ` `  `// Driver code ` `int` `main() ` `{ ` `    ``int` `arr[] = { 1, 3, 2, 7, 9, 11 }; ` `    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr[0]); ` ` `  `    ``int` `L = 1; ` `    ``int` `R = 4; ` ` `  `    ``operation(arr, n, L, R); ` ` `  `    ``return` `0; ` `} `

Output:

```16
```

Time Complexity:

• The time complexity for tree construction is O(N) where N is the size of the array.
• The time complexity for each query is O(log(N)) where N is the size of the array.

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

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.