Get the best out of our app
GeeksforGeeks App
Open App
Browser
Continue

# Queries to find the minimum index in a range [L, R] having at least value X with updates

Given an array arr[] consisting of N integers and an array Queries[] consisting of Q queries of the type {X, L, R} to perform following operations:

• If the value of X is 1, then update the array element at Xth index to L.
• Otherwise, find the minimum index j in the range [L, R] such that arr[j] ≥ X. If no such j exists, then print “-1”.

Examples:

Input: arr[] = {1, 3, 2, 4, 6}, Queries[][] = {{2, 0, 4}, {1, 2, 5}, {4, 0, 4}, {0, 0, 4}}
Output: 1 2 0
Explanation:
Query 1: find(2, 0, 4) => First element which is at least 2 is 3. So, its index is 1.
Query 2: update(2, 5) => arr[] = {1, 3, 5, 4, 6}.
Query 3: find(4, 0, 4) => First element which is at least 4 is 5. So, its index is 2.
Query 4: find(0, 0, 4) => First element which is at least 0 is 1. So, its index is 0.

Input: arr[] = {1}, Queries[][] = {{2, 0, 0}};
Output: 1 2 0
Explanation:
Query 1: find(2, 0, 0) => No element is greater than 2. Therefore, print -1.

Naive Approach: The simplest approach is to traverse the array for each query. For the queries of Type 1, update A[X] to L. For the query of Type 2, traverse the array arr[] over the range [L, R] and find the minimum index j satisfying the condition. If no such index is found, then print “-1”

Below is the implementation of the above approach:

## C++14

 `// C++ program for the above approach``#include ``using` `namespace` `std;` `// Function to find the minimum``// index j in the range [L, R]``// such that arr[j] ≥ X``int` `find(vector<``int``>& arr, ``int` `X, ``int` `L, ``int` `R)``{``    ``for` `(``int` `j = L; j <= R; j++) {``        ``if` `(arr[j] >= X) {``            ``return` `j;``        ``}``    ``}``    ``return` `-1;``}` `// Function to update the array``// element at Xth index to L``void` `update(vector<``int``>& arr, ``int` `X, ``int` `L) { arr[X] = L; }` `// Driver Code``int` `main()``{``    ``vector<``int``> arr = { 1, 3, 2, 4, 6 };``    ``vector > queries = {``        ``{ 2, 0, 4 }, { 1, 2, 5 }, { 4, 0, 4 }, { 0, 0, 4 }``    ``};` `    ``// Iterating on queries``    ``for` `(``auto` `query : queries) {``        ``int` `x = query[0], l = query[1], r = query[2];``        ``if` `(x == 1) {` `            ``// Function call for update``            ``update(arr, l, r);``        ``}``        ``else` `{` `            ``// Function call for finding``            ``// the minimum``            ``int` `j = find(arr, x, l, r);``            ``cout << j << endl;``        ``}``    ``}``    ``return` `0;``}`

Output

```1
2
0
```

Time Complexity: O(N*Q)
Auxiliary Space: O(1)

Efficient Approach: To optimize the above approach, the idea is to use Segment Tree in order to perform queries efficiently. Follow the steps below to solve the problem:

• Construct a Segment Tree where each node will represent the maximum value in the range of that node. For example, for any given range [i, j], its corresponding node will contain the maximum value in that range.
• Initialize a variable, say ans.
• Now, for queries of type 2, if the current range does not lie inside the range [L, R], then traverse its left subtree.
• Now, in the left subtree, if the maximum exceeds X and the current range lies inside the range [L, R], then go to the mid-point of that range and check if its value is greater than X or not. If found to be true, visit its left part. Otherwise, visit its right part.
• Update the variable ans as the minimum index between the given range if it exists.
• Continue the above steps, until the left part of the range becomes equal to the right part.
• After completing the above steps, print the value of ans as the result.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach``#include ``#define maxN 100``using` `namespace` `std;` `// Stores nodes value of the Tree``int` `Tree[4 * maxN];` `// Function to build segment tree``void` `build(``int` `arr[], ``int` `index,``           ``int` `s, ``int` `e)``{``    ``// Base Case``    ``if` `(s == e)``        ``Tree[index] = arr[s];` `    ``else` `{``        ``// Find the value of mid``        ``int` `m = (s + e) / 2;` `        ``// Update for left subtree``        ``build(arr, 2 * index, s, m);` `        ``// Update for right subtree``        ``build(arr, 2 * index + 1,``              ``m + 1, e);` `        ``// Update the value at the``        ``// current index``        ``Tree[index]``            ``= max(Tree[2 * index],``                  ``Tree[2 * index + 1]);``    ``}``}` `// Function for finding the index``// of the first element at least x``int` `atleast_x(``int` `index, ``int` `s, ``int` `e,``              ``int` `ql, ``int` `qr, ``int` `x)``{``    ``// If current range does``    ``// not lie in query range``    ``if` `(ql > e || qr < s)``        ``return` `-1;` `    ``// If current range is inside``    ``// of query range``    ``if` `(s <= ql && e <= qr) {` `        ``// Maximum value in this``        ``// range is less than x``        ``if` `(Tree[index] < x)``            ``return` `-1;` `        ``// Finding index of first``        ``// value in this range``        ``while` `(s != e) {``            ``int` `m = (s + e) / 2;` `            ``// Update the value of``            ``// the minimum index``            ``if` `(Tree[2 * index] >= x) {``                ``e = m;``                ``index = 2 * index;``            ``}``            ``else` `{``                ``s = m + 1;``                ``index = 2 * index + 1;``            ``}``        ``}``        ``return` `s;``    ``}` `    ``// Find mid of the current range``    ``int` `m = (s + e) / 2;` `    ``// Left subtree``    ``int` `val = atleast_x(2 * index, s,``                        ``m, ql, qr, x);` `    ``if` `(val != -1)``        ``return` `val;` `    ``// If it does not lie in``    ``// left subtree``    ``return` `atleast_x(2 * index + 1, m + 1,``                     ``e, ql, qr, x);``}` `// Function for updating segment tree``void` `update(``int` `index, ``int` `s, ``int` `e,``            ``int` `new_val, ``int` `pos)``{``    ``// Update the value, we``    ``// reached leaf node``    ``if` `(s == e)``        ``Tree[index] = new_val;` `    ``else` `{` `        ``// Find the mid``        ``int` `m = (s + e) / 2;` `        ``if` `(pos <= m) {` `            ``// If pos lies in the``            ``// left subtree``            ``update(2 * index, s, m,``                   ``new_val, pos);``        ``}``        ``else` `{` `            ``// pos lies in the``            ``// right subtree``            ``update(2 * index + 1,``                   ``m + 1, e,``                   ``new_val, pos);``        ``}` `        ``// Update the maximum value``        ``// in the range``        ``Tree[index]``            ``= max(Tree[2 * index],``                  ``Tree[2 * index + 1]);``    ``}``}` `// Function to print the answer``// for the given queries``void` `printAnswer(``int``* arr, ``int` `n)``{``    ``// Build segment tree``    ``build(arr, 1, 0, n - 1);` `    ``// Find index of first value``    ``// atleast 2 in range [0, n-1]``    ``cout << atleast_x(1, 0, n - 1,``                      ``0, n - 1, 2)``         ``<< ``"\n"``;` `    ``// Update value at index 2 to 5``    ``arr[2] = 5;``    ``update(1, 0, n - 1, 5, 2);` `    ``// Find index of first value``    ``// atleast 4 in range [0, n-1]``    ``cout << atleast_x(1, 0, n - 1,``                      ``0, n - 1, 4)``         ``<< ``"\n"``;` `    ``// Find index of first value``    ``// atleast 0 in range [0, n-1]``    ``cout << atleast_x(1, 0, n - 1,``                      ``0, n - 1, 0)``         ``<< ``"\n"``;``}` `// Driver Code``int` `main()``{``    ``int` `arr[] = { 1, 3, 2, 4, 6 };``    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr[0]);` `    ``// Function Call``    ``printAnswer(arr, N);` `    ``return` `0;``}`

## Java

 `// Java program to implement``// the above approach``import` `java.util.*;` `class` `GFG``{`` ` `static` `int` `maxN = ``100``;` `// Stores nodes value of the Tree``static` `int` `Tree[] = ``new` `int``[``4` `* maxN];` `// Function to build segment tree``static` `void` `build(``int` `arr[], ``int` `index,``           ``int` `s, ``int` `e)``{``    ``// Base Case``    ``if` `(s == e)``        ``Tree[index] = arr[s];` `    ``else``    ``{``      ` `        ``// Find the value of mid``        ``int` `m = (s + e) / ``2``;` `        ``// Update for left subtree``        ``build(arr, ``2` `* index, s, m);` `        ``// Update for right subtree``        ``build(arr, ``2` `* index + ``1``,``              ``m + ``1``, e);` `        ``// Update the value at the``        ``// current index``        ``Tree[index]``            ``= Math.max(Tree[``2` `* index],``                  ``Tree[``2` `* index + ``1``]);``    ``}``}` `// Function for finding the index``// of the first element at least x``static` `int` `atleast_x(``int` `index, ``int` `s, ``int` `e,``              ``int` `ql, ``int` `qr, ``int` `x)``{``    ``// If current range does``    ``// not lie in query range``    ``if` `(ql > e || qr < s)``        ``return` `-``1``;` `    ``// If current range is inside``    ``// of query range``    ``if` `(s <= ql && e <= qr) {` `        ``// Maximum value in this``        ``// range is less than x``        ``if` `(Tree[index] < x)``            ``return` `-``1``;` `        ``// Finding index of first``        ``// value in this range``        ``while` `(s != e) {``            ``int` `m = (s + e) / ``2``;` `            ``// Update the value of``            ``// the minimum index``            ``if` `(Tree[``2` `* index] >= x) {``                ``e = m;``                ``index = ``2` `* index;``            ``}``            ``else` `{``                ``s = m + ``1``;``                ``index = ``2` `* index + ``1``;``            ``}``        ``}``        ``return` `s;``    ``}` `    ``// Find mid of the current range``    ``int` `m = (s + e) / ``2``;` `    ``// Left subtree``    ``int` `val = atleast_x(``2` `* index, s,``                        ``m, ql, qr, x);``    ``if` `(val != -``1``)``        ``return` `val;` `    ``// If it does not lie in``    ``// left subtree``    ``return` `atleast_x(``2` `* index + ``1``, m + ``1``,``                     ``e, ql, qr, x);``}` `// Function for updating segment tree``static` `void` `update(``int` `index, ``int` `s, ``int` `e,``            ``int` `new_val, ``int` `pos)``{``  ` `    ``// Update the value, we``    ``// reached leaf node``    ``if` `(s == e)``        ``Tree[index] = new_val;``    ``else``    ``{` `        ``// Find the mid``        ``int` `m = (s + e) / ``2``;` `        ``if` `(pos <= m)``        ``{` `            ``// If pos lies in the``            ``// left subtree``            ``update(``2` `* index, s, m,``                   ``new_val, pos);``        ``}``        ``else``        ``{` `            ``// pos lies in the``            ``// right subtree``            ``update(``2` `* index + ``1``,``                   ``m + ``1``, e,``                   ``new_val, pos);``        ``}` `        ``// Update the maximum value``        ``// in the range``        ``Tree[index]``            ``= Math.max(Tree[``2` `* index],``                  ``Tree[``2` `* index + ``1``]);``    ``}``}` `// Function to print the answer``// for the given queries``static` `void` `printAnswer(``int``[] arr, ``int` `n)``{``  ` `    ``// Build segment tree``    ``build(arr, ``1``, ``0``, n - ``1``);` `    ``// Find index of first value``    ``// atleast 2 in range [0, n-1]``    ``System.out.println(atleast_x(``1``, ``0``, n - ``1``,``                      ``0``, n - ``1``, ``2``));` `    ``// Update value at index 2 to 5``    ``arr[``2``] = ``5``;``    ``update(``1``, ``0``, n - ``1``, ``5``, ``2``);` `    ``// Find index of first value``    ``// atleast 4 in range [0, n-1]``    ``System.out.println(atleast_x(``1``, ``0``, n - ``1``,``                      ``0``, n - ``1``, ``4``));` `    ``// Find index of first value``    ``// atleast 0 in range [0, n-1]``    ``System.out.println(atleast_x(``1``, ``0``, n - ``1``,``                      ``0``, n - ``1``, ``0``));``}``   ` `// Driver code``public` `static` `void` `main(String[] args)``{``    ``int` `arr[] = { ``1``, ``3``, ``2``, ``4``, ``6` `};``    ``int` `N = arr.length;` `    ``// Function Call``    ``printAnswer(arr, N);``}``}` `// This code is contributed by susmitakundugoaldanga.`

## Python3

 `# Python 3 program for the above approach``maxN ``=` `100` `# Stores nodes value of the Tree``Tree ``=` `[``0` `for` `i ``in` `range``(``4` `*` `maxN)]` `# Function to build segment tree``def` `build(arr, index, s, e):``  ` `    ``# Base Case``    ``global` `Tree``    ``global` `max``    ``if` `(s ``=``=` `e):``        ``Tree[index] ``=` `arr[s]``    ``else``:``      ` `        ``# Find the value of mid``        ``m ``=` `(s ``+` `e) ``/``/` `2` `        ``# Update for left subtree``        ``build(arr, ``2` `*` `index, s, m)` `        ``# Update for right subtree``        ``build(arr, ``2` `*` `index ``+` `1``, m ``+` `1``, e)` `        ``# Update the value at the``        ``# current index``        ``Tree[index] ``=` `max``(Tree[``2` `*` `index],``                          ``Tree[``2` `*` `index ``+` `1``])` `# Function for finding the index``# of the first element at least x``def` `atleast_x(index, s,  e,  ql, qr, x):``    ``global` `Tree``    ``global` `max``    ` `    ``# If current range does``    ``# not lie in query range``    ``if` `(ql > e ``or` `qr < s):``        ``return` `-``1` `    ``# If current range is inside``    ``# of query range``    ``if` `(s <``=` `ql ``and` `e <``=` `qr):``      ` `        ``# Maximum value in this``        ``# range is less than x``        ``if` `(Tree[index] < x):``            ``return` `-``1``;` `        ``# Finding index of first``        ``# value in this range``        ``while` `(s !``=` `e):``            ``m ``=` `(s ``+` `e) ``/``/` `2` `            ``# Update the value of``            ``# the minimum index``            ``if` `(Tree[``2` `*` `index] >``=` `x):``                ``e ``=` `m``                ``index ``=` `2` `*` `index``            ``else``:``                ``s ``=` `m ``+` `1``                ``index ``=` `2` `*` `index ``+` `1``        ``return` `s` `    ``# Find mid of the current range``    ``m ``=` `(s ``+` `e) ``/``/` `2` `    ``# Left subtree``    ``val ``=` `atleast_x(``2` `*` `index, s, m, ql, qr, x)``    ``if` `(val !``=` `-``1``):``        ``return` `val` `    ``# If it does not lie in``    ``# left subtree``    ``return` `atleast_x(``2` `*` `index ``+` `1``, m ``+` `1``,e, ql, qr, x)` `# Function for updating segment tree``def` `update(index, s, e, new_val, pos):``    ``global` `Tree``    ``global` `max``    ` `    ``# Update the value, we``    ``# reached leaf node``    ``if` `(s ``=``=` `e):``        ``Tree[index] ``=` `new_val``    ``else``:` `        ``# Find the mid``        ``m ``=` `(s ``+` `e) ``/``/` `2` `        ``if` `(pos <``=` `m):``            ``# If pos lies in the``            ``# left subtree``            ``update(``2` `*` `index, s, m,new_val, pos)``        ``else``:``            ``# pos lies in the``            ``# right subtree``            ``update(``2` `*` `index ``+` `1``, m ``+` `1``, e, new_val, pos)` `        ``# Update the maximum value``        ``# in the range``        ``Tree[index] ``=` `max``(Tree[``2` `*` `index], Tree[``2` `*` `index ``+` `1``])` `# Function to print the answer``# for the given queries``def` `printAnswer(arr, n):``    ``global` `Tree``    ``global` `max``    ` `    ``# Build segment tree``    ``build(arr, ``1``, ``0``, n ``-` `1``)` `    ``# Find index of first value``    ``# atleast 2 in range [0, n-1]``    ``print``(atleast_x(``1``, ``0``, n ``-` `1``, ``0``, n ``-` `1``, ``2``))` `    ``# Update value at index 2 to 5``    ``arr[``2``] ``=` `5``    ``update(``1``, ``0``, n ``-` `1``, ``5``, ``2``)` `    ``# Find index of first value``    ``# atleast 4 in range [0, n-1]``    ``print``(atleast_x(``1``, ``0``, n ``-` `1``, ``0``, n ``-` `1``, ``4``))` `    ``# Find index of first value``    ``# atleast 0 in range [0, n-1]``    ``print``(atleast_x(``1``, ``0``, n ``-` `1``, ``0``, n ``-` `1``, ``0``))` `# Driver Code``if` `__name__ ``=``=` `'__main__'``:``    ``arr ``=`  `[``1``, ``3``, ``2``, ``4``, ``6``]``    ``N ``=`  `len``(arr)``    ` `    ``# Function Call``    ``printAnswer(arr, N)` `    ``# This code is contributed by bgangwar59.`

## C#

 `// C# program to implement``// the above approach``using` `System;``class` `GFG``{``  ` `static` `int` `maxN = 100;` `// Stores nodes value of the Tree``static` `int``[] Tree = ``new` `int``[4 * maxN];` `// Function to build segment tree``static` `void` `build(``int``[] arr, ``int` `index,``           ``int` `s, ``int` `e)``{``    ``// Base Case``    ``if` `(s == e)``        ``Tree[index] = arr[s];` `    ``else``    ``{``      ` `        ``// Find the value of mid``        ``int` `m = (s + e) / 2;` `        ``// Update for left subtree``        ``build(arr, 2 * index, s, m);` `        ``// Update for right subtree``        ``build(arr, 2 * index + 1,``              ``m + 1, e);` `        ``// Update the value at the``        ``// current index``        ``Tree[index]``            ``= Math.Max(Tree[2 * index],``                  ``Tree[2 * index + 1]);``    ``}``}` `// Function for finding the index``// of the first element at least x``static` `int` `atleast_x(``int` `index, ``int` `s, ``int` `e,``              ``int` `ql, ``int` `qr, ``int` `x)``{``    ``// If current range does``    ``// not lie in query range``    ``if` `(ql > e || qr < s)``        ``return` `-1;` `    ``// If current range is inside``    ``// of query range``    ``if` `(s <= ql && e <= qr) {` `        ``// Maximum value in this``        ``// range is less than x``        ``if` `(Tree[index] < x)``            ``return` `-1;``    ` `        ``// Finding index of first``        ``// value in this range``        ``while` `(s != e) {``            ``int` `m = (s + e) / 2;` `            ``// Update the value of``            ``// the minimum index``            ``if` `(Tree[2 * index] >= x) {``                ``e = m;``                ``index = 2 * index;``            ``}``            ``else` `{``                ``s = m + 1;``                ``index = 2 * index + 1;``            ``}``        ``}``        ``return` `s;``    ``}` `    ``// Find mid of the current range``    ``int` `mm = (s + e) / 2;` `    ``// Left subtree``    ``int` `val = atleast_x(2 * index, s,``                        ``mm, ql, qr, x);``    ``if` `(val != -1)``        ``return` `val;` `    ``// If it does not lie in``    ``// left subtree``    ``return` `atleast_x(2 * index + 1, mm + 1,``                     ``e, ql, qr, x);``}` `// Function for updating segment tree``static` `void` `update(``int` `index, ``int` `s, ``int` `e,``            ``int` `new_val, ``int` `pos)``{``  ` `    ``// Update the value, we``    ``// reached leaf node``    ``if` `(s == e)``        ``Tree[index] = new_val;``    ``else``    ``{` `        ``// Find the mid``        ``int` `m = (s + e) / 2;` `        ``if` `(pos <= m)``        ``{` `            ``// If pos lies in the``            ``// left subtree``            ``update(2 * index, s, m,``                   ``new_val, pos);``        ``}``        ``else``        ``{` `            ``// pos lies in the``            ``// right subtree``            ``update(2 * index + 1,``                   ``m + 1, e,``                   ``new_val, pos);``        ``}` `        ``// Update the maximum value``        ``// in the range``        ``Tree[index]``            ``= Math.Max(Tree[2 * index],``                  ``Tree[2 * index + 1]);``    ``}``}` `// Function to print the answer``// for the given queries``static` `void` `printAnswer(``int``[] arr, ``int` `n)``{``  ` `    ``// Build segment tree``    ``build(arr, 1, 0, n - 1);` `    ``// Find index of first value``    ``// atleast 2 in range [0, n-1]``    ``Console.WriteLine(atleast_x(1, 0, n - 1,``                      ``0, n - 1, 2));` `    ``// Update value at index 2 to 5``    ``arr[2] = 5;``    ``update(1, 0, n - 1, 5, 2);` `    ``// Find index of first value``    ``// atleast 4 in range [0, n-1]``    ``Console.WriteLine(atleast_x(1, 0, n - 1,``                      ``0, n - 1, 4));` `    ``// Find index of first value``    ``// atleast 0 in range [0, n-1]``    ``Console.WriteLine(atleast_x(1, 0, n - 1,``                      ``0, n - 1, 0));``}` `// Driver code``static` `void` `Main()``{``    ``int``[] arr = { 1, 3, 2, 4, 6 };``    ``int` `N = arr.Length;` `    ``// Function Call``    ``printAnswer(arr, N);` `}``}` `// This code is contributed by sanjoy_62`

## Javascript

 ``

Output

```1
2
0
```

Time Complexity: O(Q*log N)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up