 Open in App
Not now

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

• Difficulty Level : Hard
• Last Updated : 16 Mar, 2023

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.

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

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:

• 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:

## CPP

 `// C++ program for range greatest ` `// pair sum query using segment tree `   `#include ` `using` `namespace` `std; `   `// Defining the node ` `struct` `node { ` `    ``int` `maxVal, greatestPSum; ` `} st; `   `// 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); `   `    ``int` `L = 1; ` `    ``int` `R = 4; `   `    ``operation(arr, n, L, R); `   `    ``return` `0; ` `} `

## Python3

 `#  Python program for range greatest` `#  pair sum query using segment tree`   `# A utility function` `def` `util(x, y):` `    ``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.` `def` `getMid(s, 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` `def` `query(ss, se, qs, qe, index, st):` `    `  `    `  `    ``# If segment of this node is a part` `    ``# of given range, then return` `    ``# the min of the segment` `    ``if` `qs <``=` `ss ``and` `qe >``=` `se:` `        ``return` `st[index]` `    `  `    ``temp ``=` `{}` `    ``temp[``'maxVal'``], temp[``'greatestPSum'``] ``=` `-``1``, ``-``1` `    `  `    ``# If segment of this node` `    ``# is outside the given range` `    ``if` `se < qs ``or` `ss > qe:` `        ``return` `temp` `    `  `    ``# If a part of this segment` `    ``# overlaps with the given range` `    ``mid ``=` `getMid(ss, se)` `    ``return` `util(query(ss, mid, qs, qe, ``2` `*` `index ``+` `1``, st), query(mid ``+` `1``, se, qs, qe, ``2` `*` `index ``+` `2``, st))`     `# Function to return the greatest pair` `#  sum in the range from index` `#  qs (query start) to qe (query end)` `def` `checkQuery(n, qs, qe, st):` `    ``temp ``=` `{}` `    ``temp[``'maxVal'``], temp[``'greatestPSum'``] ``=` `-``1``, ``-``1` `    `  `    ``# Check for erroneous input values` `    ``if` `qs < ``0` `or` `qe > n ``-` `1` `or` `qs > qe:` `        ``print``(``"Invalid Input"``)` `        ``return` `temp` `    `  `    ``return` `query(``0``, n ``-` `1``, qs, qe, ``0``, st)`     `#  A recursive function that constructs` `#  Segment Tree for array[ss..se].` `#  si is index of current node in segment tree` `def` `constructST(arr, ss, se, si, st):` `    `  `    `  `    ``# 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], ``'greatestPSum'``: ``0``}` `        ``return` `st[si]` `    `  `    `  `    ``# If there are more than one elements,` `    ``# then recur for left and right subtrees` `    ``mid ``=` `getMid(ss, se)` `    ``st[si] ``=` `util(constructST(arr, ss, mid, si ``*` `2` `+` `1``, st), constructST(arr, mid ``+` `1``, se, si ``*` `2` `+` `2``, st))` `    ``return` `st[si]`   `# Utility function to find the` `# greatest pair sum for the given` `# queries` `def` `operation(arr, n, qs, qe):` `    ``st ``=` `[{} ``for` `i ``in` `range``(``4``*``n)]` `    `  `    ``# Build segment tree from given array` `    ``constructST(arr, ``0``, n ``-` `1``, ``0``, st)` `    ``ans ``=` `checkQuery(n, qs, qe, st)` `    `  `    ``# Print minimum value in arr[qs..qe]` `    ``print``(ans[``'greatestPSum'``])`   `# Driver code` `arr ``=` `[``1``, ``3``, ``2``, ``7``, ``9``, ``11``]` `n ``=` `len``(arr)`   `L, R ``=` `1``, ``4`   `operation(arr, n, L, R)`

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.

My Personal Notes arrow_drop_up
Related Articles