# Queries to find the first array element exceeding K with updates

• Difficulty Level : Medium
• Last Updated : 05 Oct, 2021

Given an array arr[] of size N and a 2D array Q[][] consisting of queries of the following two types:

• 1 X Y: Update the array element at index X with Y.
• 2 K: Print the position of the first array element greater than or equal to K. If there is no such index, then print -1.

Examples:

Input : arr[] = { 1, 3, 2, 4, 6 }, Q[][] = {{2, 5}, {1, 3, 5}, {2, 4}, {2, 8}}
Output: 5 3 -1
Explanation:
Query1: Since arr[4] > 5, the position of arr[4] is 5.
Query2: Updating arr[2] with 5 modifies arr[] to {1, 3, 5, 4, 6}
Query3: Since arr[2] > 4, the position of arr[4] is 5.
Query4: No array element is greater than 8.

Input : arr[] = {1, 2, 3}, N = 3, Q[][] = {{2, 2}, {1, 3, 5}, {2, 10}}
Output: 2 -1

Naive Approach: The simplest approach to solve this problem is as follows:

• For a query of type 1, then update arr[X – 1] to Y.
• Otherwise, traverse the array and print the position of the first array element which is greater than or equal to K.

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

Efficient Approach: The above approach can be optimized by using segment tree. The idea is to build and update the tree using the concept of Range Maximum Query with Node Update. Follow the steps below to solve the problem:

• Build a segment tree with each node consisting of the maximum of its subtree.
• Update operation can be performed by using the concept of Range Maximum Query with Node Update
• Position of the first array element which is greater than or equal to K can be found by recursively checking for the following conditions:
• Check if the root of the left subtree is greater than or equal to K or not. If found to be true, then find the position from the left subtree. If no such array element is found in the left subtree, then recursively find the position in the right subtree.
• Otherwise, recursively find the position in the right subtree.
• Finally, print the position of an array element which is greater than or equal to K.

Below is the implementation of the above approach :

## C++

 `// C++ program to implement``// the above approach``#include ``using` `namespace` `std;` `// Function to find the mid``// of start and end``int` `getMid(``int` `s, ``int` `e) { ``return` `s + (e - s) / 2; }` `// Function to update nodes at position index``void` `updateValue(``int` `arr[], ``int``* st, ``int` `ss, ``int` `se,``                 ``int` `index, ``int` `value, ``int` `node)``{` `    ``// If index is out of range``    ``if` `(index < ss || index > se) {``        ``cout << ``"Invalid Input"` `<< endl;``        ``return``;``    ``}` `    ``// If a leaf node is found``    ``if` `(ss == se) {` `        ``// update value in array``        ``arr[index] = value;` `        ``// Update value in``        ``// the segment tree``        ``st[node] = value;``    ``}``    ``else` `{` `        ``// Stores mid of ss and se``        ``int` `mid = getMid(ss, se);` `        ``// If index is less than or``        ``// equal to mid``        ``if` `(index >= ss && index <= mid) {` `            ``// Recursively call for left subtree``            ``updateValue(arr, st, ss, mid, index, value,``                        ``2 * node + 1);``        ``}``        ``else` `{` `            ``// Recursively call for right subtree``            ``updateValue(arr, st, mid + 1, se, index, value,``                        ``2 * node + 2);``        ``}` `        ``// Update st[node]``        ``st[node] = max(st[2 * node + 1], st[2 * node + 2]);``    ``}``    ``return``;``}` `// Function to find the position of first element``// which is greater than or equal to X``int` `findMinimumIndex(``int``* st, ``int` `ss, ``int` `se, ``int` `K, ``int` `si)``{` `    ``// If no such element found in current``    ``// subtree which is greater than or``    ``// equal to K``    ``if` `(st[si] < K)``        ``return` `1e9;` `    ``// If current node is leaf node``    ``if` `(ss == se) {` `        ``// If value of current node``        ``// is greater than or equal to X``        ``if` `(st[si] >= K) {` `            ``return` `ss;``        ``}` `        ``return` `1e9;``    ``}` `    ``// Stores mid of ss and se``    ``int` `mid = getMid(ss, se);` `    ``int` `l = 1e9;` `    ``// If root of left subtree is``    ``// greater than or equal to K``    ``if` `(st[2 * si + 1] >= K)``        ``l = min(l, findMinimumIndex(st, ss, mid, K,``                                    ``2 * si + 1));` `    ``// If no such array element is``    ``// found in the left subtree``    ``if` `(l == 1e9 && st[2 * si + 2] >= K)``        ``l = min(l, findMinimumIndex(st, mid + 1, se, K,``                                    ``2 * si + 2));` `    ``return` `l;``}` `// Function to build a segment tree``int` `Build(``int` `arr[], ``int` `ss, ``int` `se, ``int``* st, ``int` `si)``{` `    ``// If current node is leaf node``    ``if` `(ss == se) {``        ``st[si] = arr[ss];``        ``return` `arr[ss];``    ``}` `    ``// store mid of ss and se``    ``int` `mid = getMid(ss, se);` `    ``// Stores maximum of left subtree and rightsubtree``    ``st[si] = max(Build(arr, ss, mid, st, si * 2 + 1),``                 ``Build(arr, mid + 1, se, st, si * 2 + 2));` `    ``return` `st[si];``}` `// Function to initialize a segment tree``// for the given array``int``* constructST(``int` `arr[], ``int` `n)``{` `    ``// Height of segment tree``    ``int` `x = (``int``)(``ceil``(log2(n)));` `    ``// Maximum size of segment tree``    ``int` `max_size = 2 * (``int``)``pow``(2, x) - 1;` `    ``// Allocate memory``    ``int``* st = ``new` `int``[max_size];` `    ``// Fill the allocated memory st``    ``Build(arr, 0, n - 1, st, 0);` `    ``// Return the constructed segment tree``    ``return` `st;``}` `// Function to perform the queries of``// the given type``void` `PerformQueries(``int` `arr[], ``int` `N,``                    ``vector > Q)``{` `    ``// Build segment tree for the given array``    ``int``* st = constructST(arr, N);` `    ``// Traverse the query array``    ``for` `(``int` `i = 0; i < Q.size(); i++) {` `        ``// If query of type 1 found``        ``if` `(Q[i][0] == 1)` `            ``updateValue(arr, st, 0, N - 1, Q[i][1] - 1, 5,``                        ``0);``        ``else` `{` `            ``// Stores index of first array element``            ``// which is greater than or equal``            ``// to Q[i][1]``            ``int` `f = findMinimumIndex(st, 0, N - 1, Q[i][1],``                                     ``0);``            ``if` `(f < N)``                ``cout << f + 1 << ``" "``;``            ``else``                ``cout << -1 << ``" "``;``        ``}``    ``}``}` `// Driver Code``int` `main()``{``    ``int` `arr[] = { 1, 3, 2, 4, 6 };` `    ``vector > Q{``        ``{ 2, 5 }, { 1, 3, 5 }, { 2, 4 }, { 2, 8 }``    ``};``    ``int` `N = ``sizeof``(arr) / ``sizeof``(arr[0]);` `    ``PerformQueries(arr, N, Q);``    ``return` `0;``}`

## Java

 `// Java program to implement``// the above approach` `import` `java.io.*;``class` `GFG``{` `  ``// Function to find the mid``  ``// of start and end``  ``static` `int` `getMid(``int` `s, ``int` `e)``  ``{``    ``return` `s + (e - s) / ``2``;``  ``}``  ``static` `void` `updateValue(``int` `arr[], ``int``[] st, ``int` `ss,``                          ``int` `se, ``int` `index, ``int` `value,``                          ``int` `node)``  ``{` `    ``// If index is out of range``    ``if` `(index < ss || index > se)``    ``{``      ``System.out.println(``"Invalid Input"``);``      ``return``;``    ``}` `    ``// If a leaf node is found``    ``if` `(ss == se)``    ``{` `      ``// update value in array``      ``arr[index] = value;` `      ``// Update value in``      ``// the segment tree``      ``st[node] = value;``    ``}``    ``else``    ``{` `      ``// Stores mid of ss and se``      ``int` `mid = getMid(ss, se);` `      ``// If index is less than or``      ``// equal to mid``      ``if` `(index >= ss && index <= mid)``      ``{` `        ``// Recursively call for left subtree``        ``updateValue(arr, st, ss, mid, index, value,``                    ``2` `* node + ``1``);``      ``}``      ``else``      ``{` `        ``// Recursively call for right subtree``        ``updateValue(arr, st, mid + ``1``, se, index,``                    ``value, ``2` `* node + ``2``);``      ``}` `      ``// Update st[node]``      ``st[node] = Math.max(st[``2` `* node + ``1``],``                          ``st[``2` `* node + ``2``]);``    ``}``  ``}` `  ``// Function to find the position of first element``  ``// which is greater than or equal to X``  ``static` `int` `findMinimumIndex(``int``[] st, ``int` `ss, ``int` `se,``                              ``int` `K, ``int` `si)``  ``{` `    ``// If no such element found in current``    ``// subtree which is greater than or``    ``// equal to K``    ``if` `(st[si] < K)``      ``return` `1000000000``;` `    ``// If current node is leaf node``    ``if` `(ss == se)``    ``{` `      ``// If value of current node``      ``// is greater than or equal to X``      ``if` `(st[si] >= K)``      ``{``        ``return` `ss;``      ``}``      ``return` `1000000000``;``    ``}` `    ``// Stores mid of ss and se``    ``int` `mid = getMid(ss, se);` `    ``int` `l = ``1000000000``;` `    ``// If root of left subtree is``    ``// greater than or equal to K``    ``if` `(st[``2` `* si + ``1``] >= K)``      ``l = Math.min(l, findMinimumIndex(st, ss, mid, K,``                                       ``2` `* si + ``1``));` `    ``// If no such array element is``    ``// found in the left subtree``    ``if` `(l == 1e9 && st[``2` `* si + ``2``] >= K)``      ``l = Math.min(l,``                   ``findMinimumIndex(st, mid + ``1``, se,``                                    ``K, ``2` `* si + ``2``));` `    ``return` `l;``  ``}` `  ``// Function to build a segment tree``  ``static` `int` `Build(``int` `arr[], ``int` `ss, ``int` `se, ``int``[] st,``                   ``int` `si)``  ``{` `    ``// If current node is leaf node``    ``if` `(ss == se)``    ``{``      ``st[si] = arr[ss];``      ``return` `arr[ss];``    ``}` `    ``// store mid of ss and se``    ``int` `mid = getMid(ss, se);` `    ``// Stores maximum of left subtree and rightsubtree``    ``st[si] = Math.max(``      ``Build(arr, ss, mid, st, si * ``2` `+ ``1``),``      ``Build(arr, mid + ``1``, se, st, si * ``2` `+ ``2``));` `    ``return` `st[si];``  ``}` `  ``// Function to initialize a segment tree``  ``// for the given array``  ``static` `int``[] constructST(``int` `arr[], ``int` `n)``  ``{` `    ``// Height of segment tree``    ``int` `x = (``int``)Math.ceil(Math.log(n) / Math.log(``2``));` `    ``// Maximum size of segment tree``    ``int` `max_size = ``2` `* (``int``)Math.pow(``2``, x) - ``1``;` `    ``// Allocate memory``    ``int``[] st = ``new` `int``[max_size];` `    ``// Fill the allocated memory st``    ``Build(arr, ``0``, n - ``1``, st, ``0``);` `    ``// Return the constructed segment tree``    ``return` `st;``  ``}``  ``static` `void` `PerformQueries(``int` `arr[], ``int` `N, ``int``[][] Q)``  ``{` `    ``// Build segment tree for the given array``    ``int``[] st = constructST(arr, N);` `    ``// Traverse the query array``    ``for` `(``int` `i = ``0``; i < Q.length; i++)``    ``{` `      ``// If query of type 1 found``      ``if` `(Q[i][``0``] == ``1``)``        ``updateValue(arr, st, ``0``, N - ``1``, Q[i][``1``] - ``1``,``                    ``5``, ``0``);``      ``else` `{` `        ``// Stores index of first array element``        ``// which is greater than or equal``        ``// to Q[i][1]``        ``int` `f = findMinimumIndex(st, ``0``, N - ``1``,``                                 ``Q[i][``1``], ``0``);``        ``if` `(f < N)``          ``System.out.print(f + ``1` `+ ``" "``);``        ``else``          ``System.out.print(-``1` `+ ``" "``);``      ``}``    ``}``  ``}` `  ``// Driver Code``  ``public` `static` `void` `main(String[] args)``  ``{``    ``int` `arr[] = { ``1``, ``3``, ``2``, ``4``, ``6` `};``    ` `    ``int``[][] Q``      ``= { { ``2``, ``5` `}, { ``1``, ``3``, ``5` `}, { ``2``, ``4` `}, { ``2``, ``8` `} };``    ``int` `N = arr.length;``    ``PerformQueries(arr, N, Q);``  ``}``}` `// This code is contributed by hemanthsawarna1506`

## Python3

 `# Python3 program to implement``# the above approach``import` `math` `# Function to find the mid``# of start and end``def` `getMid(s,e):``    ``return` `s ``+` `math.floor((e ``-` `s) ``/` `2``)`` ` `def` `updateValue(arr,st,ss,se,index,value,node):``    ``# If index is out of range``    ``if` `(index < ss ``or` `index > se):``      ``print``(``"Invalid Input"``)``      ``return``  ` `    ``# If a leaf node is found``    ``if` `(ss ``=``=` `se):``      ``# update value in array``      ``arr[index] ``=` `value``  ` `      ``# Update value in``      ``# the segment tree``      ``st[node] ``=` `value``    ``else``:``      ``# Stores mid of ss and se``      ``mid ``=` `getMid(ss, se)``  ` `      ``# If index is less than or``      ``# equal to mid``      ``if` `(index >``=` `ss ``and` `index <``=` `mid):``        ` `        ``# Recursively call for left subtree``        ``updateValue(arr, st, ss, mid, index, value, ``2` `*` `node ``+` `1``)``      ``else``:``        ` `        ``# Recursively call for right subtree``        ``updateValue(arr, st, mid ``+` `1``, se, index, value, ``2` `*` `node ``+` `2``)``  ` `      ``# Update st[node]``      ``st[node] ``=` `max``(st[``2` `*` `node ``+` `1``], st[``2` `*` `node ``+` `2``])`` ` `# Function to find the position of first element``# which is greater than or equal to X``def` `findMinimumIndex(st, ss, se, K, si):``    ``# If no such element found in current``    ``# subtree which is greater than or``    ``# equal to K``    ``if` `(st[si] < K):``      ``return` `1000000000``  ` `    ``# If current node is leaf node``    ``if` `(ss ``=``=` `se):``      ``# If value of current node``      ``# is greater than or equal to X``      ``if` `(st[si] >``=` `K):``        ``return` `ss``      ``return` `1000000000``  ` `    ``# Stores mid of ss and se``    ``mid ``=` `getMid(ss, se)``  ` `    ``l ``=` `1000000000``  ` `    ``# If root of left subtree is``    ``# greater than or equal to K``    ``if` `(st[``2` `*` `si ``+` `1``] >``=` `K):``      ``l ``=` `min``(l, findMinimumIndex(st, ss, mid, K, ``2` `*` `si ``+` `1``))``  ` `    ``# If no such array element is``    ``# found in the left subtree``    ``if` `(l ``=``=` `1e9` `and` `st[``2` `*` `si ``+` `2``] >``=` `K):``      ``l ``=` `min``(l, findMinimumIndex(st, mid ``+` `1``, se, K, ``2` `*` `si ``+` `2``))``  ` `    ``return` `l`` ` `# Function to build a segment tree``def` `Build(arr, ss, se, st, si):``  ` `    ``# If current node is leaf node``    ``if` `(ss ``=``=` `se):``      ``st[si] ``=` `arr[ss]``      ``return` `arr[ss]``  ` `    ``# store mid of ss and se``    ``mid ``=` `getMid(ss, se)``  ` `    ``# Stores maximum of left subtree and rightsubtree``    ``st[si] ``=` `max``(Build(arr, ss, mid, st, si ``*` `2` `+` `1``), Build(arr, mid ``+` `1``, se, st, si ``*` `2` `+` `2``))``  ` `    ``return` `st[si]`` ` `# Function to initialize a segment tree``# for the given array``def` `constructST(arr,n):``  ` `    ``# Height of segment tree``    ``x ``=` `math.ceil(math.log(n) ``/` `math.log(``2``))``  ` `    ``# Maximum size of segment tree``    ``max_size ``=` `2` `*` `pow``(``2``, x) ``-` `1``  ` `    ``# Allocate memory``    ``st ``=` `[``0``]``*``(max_size)``  ` `    ``# Fill the allocated memory st``    ``Build(arr, ``0``, n ``-` `1``, st, ``0``)``  ` `    ``# Return the constructed segment tree``    ``return` `st`` ` `def` `PerformQueries(arr, N, Q):``  ` `    ``# Build segment tree for the given array``    ``st ``=` `constructST(arr, N)``  ` `    ``# Traverse the query array``    ``for` `i ``in` `range``(``len``(Q)):``      ` `      ``# If query of type 1 found``      ``if` `(Q[i][``0``] ``=``=` `1``):``        ``updateValue(arr, st, ``0``, N ``-` `1``, Q[i][``1``] ``-` `1``, ``5``, ``0``)``      ``else``:``        ``# Stores index of first array element``        ``# which is greater than or equal``        ``# to Q[i][1]``        ``f ``=` `findMinimumIndex(st, ``0``, N ``-` `1``, Q[i][``1``], ``0``)``        ``if` `(f < N):``          ``print``((f ``+` `1` `), end ``=` `" "``)``        ``else``:``          ``print``(``-``1``, end ``=` `" "``)` `# Driver code``arr ``=` `[``1``, ``3``, ``2``, ``4``, ``6` `]``Q``=` `[[ ``2``, ``5` `], [ ``1``, ``3``, ``5` `], [``2``, ``4` `], [ ``2``, ``8` `]]``N ``=` `len``(arr)` `PerformQueries(arr, N, Q)` `# This code is contributed by decode2207.`

## C#

 `// C# program to implement``// the above approach``using` `System;` `class` `GFG{` `// Function to find the mid``// of start and end``static` `int` `getMid(``int` `s, ``int` `e)``{``    ``return` `s + (e - s) / 2;``}` `static` `void` `updateValue(``int``[] arr, ``int``[] st, ``int` `ss,``                        ``int` `se, ``int` `index, ``int` `value,``                        ``int` `node)``{``    ` `    ``// If index is out of range``    ``if` `(index < ss || index > se)``    ``{``        ``Console.WriteLine(``"Invalid Input"``);``        ``return``;``    ``}` `    ``// If a leaf node is found``    ``if` `(ss == se)``    ``{``        ` `        ``// Update value in array``        ``arr[index] = value;` `        ``// Update value in``        ``// the segment tree``        ``st[node] = value;``    ``}``    ``else``    ``{``        ` `        ``// Stores mid of ss and se``        ``int` `mid = getMid(ss, se);` `        ``// If index is less than or``        ``// equal to mid``        ``if` `(index >= ss && index <= mid)``        ``{``            ` `            ``// Recursively call for left subtree``            ``updateValue(arr, st, ss, mid, index, value,``                        ``2 * node + 1);``        ``}``        ``else``        ``{``            ` `            ``// Recursively call for right subtree``            ``updateValue(arr, st, mid + 1, se, index,``                        ``value, 2 * node + 2);``        ``}` `        ``// Update st[node]``        ``st[node] = Math.Max(st[2 * node + 1],``                            ``st[2 * node + 2]);``    ``}``}` `// Function to find the position of first element``// which is greater than or equal to X``static` `int` `findMinimumIndex(``int``[] st, ``int` `ss, ``int` `se,``                            ``int` `K, ``int` `si)``{``    ` `    ``// If no such element found in current``    ``// subtree which is greater than or``    ``// equal to K``    ``if` `(st[si] < K)``        ``return` `1000000000;` `    ``// If current node is leaf node``    ``if` `(ss == se)``    ``{``        ` `        ``// If value of current node``        ``// is greater than or equal to X``        ``if` `(st[si] >= K)``        ``{``            ``return` `ss;``        ``}``        ``return` `1000000000;``    ``}` `    ``// Stores mid of ss and se``    ``int` `mid = getMid(ss, se);` `    ``int` `l = 1000000000;` `    ``// If root of left subtree is``    ``// greater than or equal to K``    ``if` `(st[2 * si + 1] >= K)``        ``l = Math.Min(l, findMinimumIndex(st, ss, mid, K,``                                         ``2 * si + 1));` `    ``// If no such array element is``    ``// found in the left subtree``    ``if` `(l == 1e9 && st[2 * si + 2] >= K)``        ``l = Math.Min(l,``                     ``findMinimumIndex(st, mid + 1, se,``                                    ``K, 2 * si + 2));` `    ``return` `l;``}` `// Function to build a segment tree``static` `int` `Build(``int``[] arr, ``int` `ss, ``int` `se,``                 ``int``[] st, ``int` `si)``{``    ` `    ``// If current node is leaf node``    ``if` `(ss == se)``    ``{``        ``st[si] = arr[ss];``        ``return` `arr[ss];``    ``}` `    ``// Store mid of ss and se``    ``int` `mid = getMid(ss, se);` `    ``// Stores maximum of left subtree and rightsubtree``    ``st[si] = Math.Max(``        ``Build(arr, ss, mid, st, si * 2 + 1),``        ``Build(arr, mid + 1, se, st, si * 2 + 2));` `    ``return` `st[si];``}` `// Function to initialize a segment tree``// for the given array``static` `int``[] constructST(``int``[] arr, ``int` `n)``{``    ` `    ``// Height of segment tree``    ``int` `x = (``int``)Math.Ceiling(Math.Log(n) /``                              ``Math.Log(2));` `    ``// Maximum size of segment tree``    ``int` `max_size = 2 * (``int``)Math.Pow(2, x) - 1;` `    ``// Allocate memory``    ``int``[] st = ``new` `int``[max_size];` `    ``// Fill the allocated memory st``    ``Build(arr, 0, n - 1, st, 0);` `    ``// Return the constructed segment tree``    ``return` `st;``}` `static` `void` `PerformQueries(``int``[] arr, ``int` `N, ``int``[][] Q)``{``    ` `    ``// Build segment tree for the given array``    ``int``[] st = constructST(arr, N);` `    ``// Traverse the query array``    ``for``(``int` `i = 0; i < Q.Length; i++)``    ``{``        ` `        ``// If query of type 1 found``        ``if` `(Q[i][0] == 1)``            ``updateValue(arr, st, 0, N - 1,``                        ``Q[i][1] - 1, 5, 0);``        ``else``        ``{``            ` `            ``// Stores index of first array element``            ``// which is greater than or equal``            ``// to Q[i][1]``            ``int` `f = findMinimumIndex(st, 0, N - 1,``                                     ``Q[i][1], 0);``            ``if` `(f < N)``                ``Console.Write(f + 1 + ``" "``);``            ``else``                ``Console.Write(-1 + ``" "``);``        ``}``    ``}``}` `// Driver Code``public` `static` `void` `Main(``string``[] args)``{``    ``int``[] arr = { 1, 3, 2, 4, 6 };``    ``int``[][] Q = ``new` `int``[4][];` `    ``// Initialize the elements``    ``Q[0] = ``new` `int``[] { 2, 5 };``    ``Q[1] = ``new` `int``[] { 1, 3, 5 };``    ``Q[2] = ``new` `int``[] { 2, 4 };``    ``Q[3] = ``new` `int``[] { 2, 8 };` `    ``int` `N = arr.Length;``    ``PerformQueries(arr, N, Q);``}``}` `// This code is contributed by ukasp`

## Javascript

 ``

Output:

`5 3 -1 `

My Personal Notes arrow_drop_up