Skip to content
Related Articles

Related Articles

Find the Array formed by performing Q queries on an empty array

Improve Article
Save Article
  • Difficulty Level : Hard
  • Last Updated : 27 Oct, 2022
Improve Article
Save Article

Consider an integer sequence S, which is initially empty (i.e. S = {}). Also given are Q queries, each of which is one of the following types:

  • 1 a b: Insert a and b into the sequence S.
  • 2 a b: In the sequence S, among the elements that are less than or equal to a, print b-th largest element. If no such element exist, print -1.
  • 3 a b: In the sequence S, among the elements that are greater than or equal to a, print b-th smallest element. If no such element exist, print -1

The task is to print the final sequence formed after performing all the Q queries.

Examples:

Input: Q = 7, A = {{1, {20, 10}}, {1, {30, 20}}, {3, {15, 1}}, {3, {15, 2}}, {3, {15, 3}}, {3, {15, 4}}, {2, {100, 5}} }
Output: 20, 20, 30, -1, -1
Explanation: Initially sequence S={}. 
=> After execution of initial 2 queries, it becomes: {20, 10, 30, 20}.
=> In the sequence, elements greater than 15 are 20, 20 and 30. In 3rd query, we have to print the 1st smallest number greater than or equal to 15 which is 20.
=> Similarly, 2nd and 3rd smallest integer which are greater than 15 are 20 and 30 respectively. Now, 6th query asks us the 4th smallest integer which is greater than or equal to 15. But, there are only 3 integers greater than 15, so we print -1. => The last Query asks us the 5th largest integer in the integers less than or equal to 100. But, there are only 4 integers (10, 20, 20, 30), which are less than or equal to 100. So, we print -1.

Input: Q = 6, A = {{1, {5, 7}}, {1, {2, 15}}, {1, {11, 16}}, {3, {14, 2}}, {2, {11, 3}}, {2, {10, 10}} }
Output: 16, 5, -1

 

Approach: The problem can be solved using binary search and multiset.

  • Initialize the sequence as a multiset (say s).
  • Iterate through the vector A to process the queries.
  • If the query is of type-1, insert both a and b into the multiset.
  • If the query is of type-2,  we calculate the lower bound of a in s and from that lower bound we decrement b times to get the b-th largest element less than or equal to a.
  • If the query is of type-3, we calculate the upper bound of a in s and from that upper bound we increment b times to get the b-th smallest element greater than or equal to a.
  • In queries of type-2 or 3, if iterator goes beyond s.begin() or s.end(), print answer to that query as -1. Else, print the answer obtained through above two steps.

Following is the code based on above approach:

C++




// C++ code for Find the sequence after
// performing Q queries
#include <bits/stdc++.h>
using namespace std;
 
// function to perform the given queries on s
void solveQueries(int Q,
                  vector<pair<int, pair<int, int> > >& A)
{
    // initializing variable to store answer
    // to current query and a multiset of integers
    int ans;
    multiset<int> s;
 
    // iterating through all queries
    for (int i = 0; i < Q; i++) {
        int t, a, b;
        t = A[i].first;
        a = A[i].second.first;
        b = A[i].second.second;
 
        // if query is of 1st type, we simply
        // insert both a and b into our sequence
        if (t == 1) {
            s.insert(a);
            s.insert(b);
            continue;
        }
 
        // If query is of the second type, we
        // calculate the lower bound of a
        // and from that lower bound we decrement
        // b times to get the bth largest element
        // less than or equal to a
        if (t == 2) {
            ans = 0;
            auto it = s.upper_bound(a);
            for (int j = 0; j < b; j++) {
                if (it == s.begin()) {
                    ans = -1;
                    break;
                }
                it--;
                ans = *it;
            }
        }
 
        // If query is of the third type,
        // we calculate the upper bound of a and
        // from that upper bound we increment b times
        // to get the bth smallest element greater
        // than or equal to a
        else {
            ans = 0;
            auto it = s.lower_bound(a);
            for (int j = 0; j < b; j++) {
                if (it == s.end()) {
                    ans = -1;
                    break;
                }
                ans = *it;
                it++;
            }
        }
        // printing the answer
        cout << ans << " ";
    }
}
 
// Driver Code
int main()
{
    int Q = 7;
    vector<pair<int, pair<int, int> > > A
        = { { 1, { 20, 10 } }, { 1, { 30, 20 } }, { 3, { 15, 1 } }, { 3, { 15, 2 } }, { 3, { 15, 3 } }, { 3, { 15, 4 } }, { 2, { 100, 5 } } };
    solveQueries(Q, A);
}


Python3




# Python code for Find the sequence after
# performing Q queries
 
# function to calculate lower bound
from xml.dom.minidom import Document
 
def lowerbound(arr,target):
    N = len(arr);
    low = 0;
 
    for i in range(N - 1):
        if(arr[i] < target and arr[i + 1] >= target):
            low = i+1;
            break;
     
    if(arr[0] > target): return 0;
    return low;
 
 
# function to calculate lower bound
def upperbound(arr,target):
    N = len(arr);
    high = N;
 
    for i in range(N - 1, 0, -1):
        if(arr[i] >= target and arr[i - 1] < target):
            high = i;
            break;
         
    if(high == N): return N;
    return high;
 
# function to perform the given queries on s
ansArray = "";
 
def solveQueries(Q,A):
    # initializing variable to store answer
    # to current query and a multiset of integers
     
    s = [];
    # iterating through all queries
    for i in range(Q):
         
        t = A[i]["first"];
        a = A[i]["second"]["first"];
        b = A[i]["second"]["second"];
 
        # if query is of 1st type, we simply
        # insert both a and b into our sequence
        if (t == 1):
            s.append(a);
            s.append(b);
            continue;
         
        s.sort();
         
        # If query is of the second type, we
        # calculate the lower bound of a
        # and from that lower bound we decrement
        # b times to get the bth largest element
        # less than or equal to a
        if (t == 2):
            ans = 0;
            it = upperbound(s,a);
            for j in range(b):
                if (it == 0):
                    ans = -1;
                    break;
                 
                it -= 1
                ans = s[it];
             
 
        # If query is of the third type,
        # we calculate the upper bound of a and
        # from that upper bound we increment b times
        # to get the bth smallest element greater
        # than or equal to a
        else:
            ans = 0;
            it = lowerbound(s,a);
            for j in range(b):
                if (it == len(s)):
                    ans = -1;
                    break;
                ans = s[it];
                it += 1
             
        # printing(storing) the answer
        global ansArray
        ansArray += str(ans) + " ";
     
# Driver Code
Q = 7;
A = [ {"first" : 1, "second" : {"first" : 20, "second" : 10} },
{"first" : 1, "second" : {"first" : 30, "second" : 20} },
{"first" : 3, "second" : {"first" : 15, "second" : 1} },
{"first" : 3, "second" : {"first" : 15, "second" : 2} },
{"first" : 3, "second" : {"first" : 15, "second" : 3} },
{"first" : 3, "second" : {"first" : 15, "second" : 4} },
{"first" : 2, "second" : {"first" : 100, "second" : 5} }
]
solveQueries(Q, A);
 
# printing answer
print(ansArray);
 
# This code is contributed by Saurabh Jaiswal


Javascript




<script>
 
// Javascript code for Find the sequence after
// performing Q queries
 
// function to calculate lower bound
function lowerbound(arr,target)
{
    let N = arr.length;
    let low=0;
 
    for(let i=0;i<N-1;i++)
    {
        if(arr[i]<target && arr[i+1]>=target)
        {
            low = i+1;
            break;
        }
    }
    if(arr[0]>target) return 0;
    return low;
}
 
// function to calculate lower bound
function upperbound(arr,target)
{
    let N = arr.length;
    let high=N;
 
    for(let i=N-1;i>=0;i--)
    {
        if(arr[i]>=target && arr[i-1]<target)
        {
            high = i;
            break;
        }
    }
 
    if(high = N) return N;
    return high;
}
 
 
// function to perform the given queries on s
let ansArray = "";
function solveQueries(Q,A)
{
    // initializing variable to store answer
    // to current query and a multiset of integers
    let ans;
     
    let s = [];
    // iterating through all queries
    for (let i = 0; i < Q; i++) {
         
        let t = A[i].first;
        let a = A[i].second.first;
        let b = A[i].second.second;
 
        // if query is of 1st type, we simply
        // insert both a and b into our sequence
        if (t == 1) {
            s.push(a);
            s.push(b);
            continue;
        }
        s.sort();
         
        // If query is of the second type, we
        // calculate the lower bound of a
        // and from that lower bound we decrement
        // b times to get the bth largest element
        // less than or equal to a
        if (t == 2) {
            ans = 0;
            let it = upperbound(s,a);
            for (let j = 0; j < b; j++) {
                if (it == 0) {
                    ans = -1;
                    break;
                }
                it--;
                ans = s[it];
            }
        }
 
        // If query is of the third type,
        // we calculate the upper bound of a and
        // from that upper bound we increment b times
        // to get the bth smallest element greater
        // than or equal to a
        else {
            ans = 0;
            let it = lowerbound(s,a);
            for (let j = 0; j < b; j++) {
                if (it == s.length) {
                    ans = -1;
                    break;
                }
                ans = s[it];
                it++;
            }
        }
        // printing(storing) the answer
        ansArray+=ans + " ";
    }
     
}
 
 
 
// Driver Code
let Q = 7;
let A = [ {"first" : 1, "second" : {"first" : 20, "second" : 10} },
{"first" : 1, "second" : {"first" : 30, "second" : 20} },
{"first" : 3, "second" : {"first" : 15, "second" : 1} },
{"first" : 3, "second" : {"first" : 15, "second" : 2} },
{"first" : 3, "second" : {"first" : 15, "second" : 3} },
{"first" : 3, "second" : {"first" : 15, "second" : 4} },
{"first" : 2, "second" : {"first" : 100, "second" : 5} }
]
solveQueries(Q, A);
 
// printing answer
console.log(ansArray);
 
// This code is contributed by akashish__
 
</script>


Output

20 20 30 -1 -1 

Time Complexity: O(Q*log(Q)), where Q is the number of queries
Auxiliary Space: O(Q)


My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!