Given an array arr[] of size N and a set Q[][] containing M queries, the task is to execute the queries on the given array such that there can be two types of queries:

**Type 1:**[i, x] – Update the element at i^{th}index to x.**Type 2:**[k] – Find the k^{th}smallest element in the array.

**Examples:**

Input:arr[] = {4, 3, 6, 2}, Q[][] = {{1, 2, 5}, {2, 3}, {1, 1, 7}, {2, 1}}

Output:5 2

Explanation:

For the 1^{st}query: arr[] = {4, 5, 6, 2}

For the 2^{nd}query: 3^{rd}smallest element would be 5.

For the 3^{rd}query: arr[] = {7, 5, 6, 2}

For the 4^{th}query: 1^{st}smallest element would be 2.

Input:arr[] = {1, 0, 4, 2, 0}, Q[][] = {{1, 2, 1}, {2, 2}, {1, 4, 5}, {1, 3, 7}, {2, 1}, {2, 5}}

Output:1 0 7

**Naive Approach:** The naive approach for this problem is to update the i^{th} element in an array in constant time and use sorting to find the K^{th} smallest element.

**Time Complexity:** O(M * (N * log(N))) where M is the number of queries and N is the size of the array.

**Efficient Approach:** The idea is to use a policy-based data structure similar to a set.

Here, a tree based container is used to store the array in the form of a sorted tree such that all the nodes to the left are smaller than the root and all the nodes to the right are greater than the root. The following are the properties of the data structure:

- It is indexed by maintaining node invariant where each node contains a count of nodes in its subtree.
- Every time we insert a new node or delete a node, we can maintain the invariant in O(logN) time by bubbling up to the root.
- So the count of the node in its left subtree gives the
**index**of that node in sorted order because the value of every node of the left subtree is smaller than the parent node.

Therefore, the idea is to follow the following approach for each query:

**Type 1:**For this query, we update the i^{th}element of the array. Therefore, we need to update the element both in the array and the data structure. In order to update the value in the tree container, the value arr[i] is found in the tree, deleted from the tree and the updated value is inserted back into the tree.**Type 2:**In order to find the K^{th}smallest element, find_by_order(K – 1) is used on the tree as the data is a sorted data. This is similar to Binary Search operation on the sorted array.

Below is the implementation of the above approach:

`// C++ implementation of the above approach ` ` ` `#include <bits/stdc++.h> ` `#include <ext/pb_ds/assoc_container.hpp> ` `#include <ext/pb_ds/tree_policy.hpp> ` `using` `namespace` `std; ` `using` `namespace` `__gnu_pbds; ` ` ` `// Defining the policy based Data Structure ` `typedef` `tree<pair<` `int` `, ` `int` `>, ` ` ` `null_type, ` ` ` `less<pair<` `int` `, ` `int` `> >, ` ` ` `rb_tree_tag, ` ` ` `tree_order_statistics_node_update> ` ` ` `indexed_set; ` ` ` `// Elements in the array are not unique, ` `// so a pair is used to give uniqueness ` `// by incrementing cnt and assigning ` `// with array elements to insert in mySet ` `int` `cnt = 0; ` ` ` `// Variable to store the data in the ` `// policy based Data Structure ` `indexed_set mySet; ` ` ` `// Function to insert the elements ` `// of the array in mySet ` `void` `insert(` `int` `n, ` `int` `arr[]) ` `{ ` ` ` `for` `(` `int` `i = 0; i < n; i++) { ` ` ` `mySet.insert({ arr[i], cnt }); ` ` ` `cnt++; ` ` ` `} ` `} ` ` ` `// Function to update the value in ` `// the data structure ` `void` `update(` `int` `x, ` `int` `y) ` `{ ` ` ` `// Get the pointer of the element ` ` ` `// in mySet which has to be updated ` ` ` `auto` `it = mySet.lower_bound({ y, 0 }); ` ` ` ` ` `// Delete from mySet ` ` ` `mySet.erase(it); ` ` ` ` ` `// Insert the updated value in mySet ` ` ` `mySet.insert({ x, cnt }); ` ` ` `cnt++; ` `} ` ` ` `// Function to find the K-th smallest ` `// element in the set ` `int` `get(` `int` `k) ` `{ ` ` ` `// Find the pointer to the kth smallest element ` ` ` `auto` `it = mySet.find_by_order(k - 1); ` ` ` `return` `(it->first); ` `} ` ` ` `// Function to perform the queries on the set ` `void` `operations(` `int` `arr[], ` `int` `n, ` ` ` `vector<vector<` `int` `> > query, ` `int` `m) ` `{ ` ` ` `// To insert the element in mySet ` ` ` `insert(n, arr); ` ` ` ` ` `// Iterating through the queries ` ` ` `for` `(` `int` `i = 0; i < m; i++) { ` ` ` ` ` `// Checking if the query is of type 1 ` ` ` `// or type 2 ` ` ` `if` `(query[i][0] == 1) { ` ` ` ` ` `// The array is 0-indexed ` ` ` `int` `j = query[i][1] - 1; ` ` ` `int` `x = query[i][2]; ` ` ` ` ` `// Update the element in mySet ` ` ` `update(x, arr[j]); ` ` ` ` ` `// Update the element in the array ` ` ` `arr[j] = x; ` ` ` `} ` ` ` `else` `{ ` ` ` `int` `K = query[i][1]; ` ` ` ` ` `// Print Kth smallest element ` ` ` `cout << get(K) << endl; ` ` ` `} ` ` ` `} ` `} ` ` ` `// Driver code ` `int` `main() ` `{ ` ` ` `int` `n = 5, m = 6, arr[] = { 1, 0, 4, 2, 0 }; ` ` ` ` ` `vector<vector<` `int` `> > query = { { 1, 2, 1 }, ` ` ` `{ 2, 2 }, ` ` ` `{ 1, 4, 5 }, ` ` ` `{ 1, 3, 7 }, ` ` ` `{ 2, 1 }, ` ` ` `{ 2, 5 } }; ` ` ` ` ` `operations(arr, n, query, m); ` ` ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

**Output:**

1 0 7

**Time Complexity:** Since every operation takes O(Log(N)) time and there are M queries, the overall time complexity is **O(M * Log(N))**.

## Recommended Posts:

- Find K-th smallest element in an array for multiple queries
- Queries to update each element in subarray to Bitwise XOR with a given value
- Queries to update a given index and find gcd in range
- Sum of even values and update queries on an array
- Range and Update Sum Queries with Factorial
- Find the element having maximum set bits in the given range for Q queries
- Range Queries to find the Element having Maximum Digit Sum
- Index of kth set bit in a binary array with update queries
- Range Update Queries to XOR with 1 in a Binary Array.
- Range Sum Queries and Update with Square Root
- Perform append, update, delete and range sum queries on the given array
- Queries to return the absolute difference between L-th smallest number and the R-th smallest number
- Queries for Composite numbers in subarray (With Point Updates)
- Binary Indexed Tree : Range Updates and Point Queries
- Binary Indexed Tree : Range Update and Range Queries
- Dynamic Segment Trees : Online Queries for Range Sum with Point Updates
- Array range queries for searching an element
- Largest interval in an Array that contains the given element X for Q queries
- Most frequent element in Array after replacing given index by K for Q queries
- Queries to search an element in an array and move it to front after every query

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.