Open In App

Implementing upper_bound() and lower_bound() for Ordered Set in C++

Prerequisites: Ordered Set and GNU C++ PBDS 
Given an ordered set set and a key K, the task is to find the upper bound and lower bound of the element K in the set in C++. If the element is not present or either of the bounds could not be calculated, then print -1.
 

Ordered set is a policy based data structure in g++ that keeps the unique elements in sorted order. It performs all the operations as performed by the set data structure in STL in log(n) complexity. Apart from that, it performs two additional operations also in log(n) complexity like: 
1. order_of_key (K): Number of items strictly smaller than K. 
2. find_by_order(K): Kth element in a set (counting from zero). 
 



Examples: 

Input: set[] = {10, 20, 30, 40, 50, 60}, K = 30 
Output: 
Lower Bound of 30: 30 
Upper Bound of 30: 40 
Explanation: 
The lower bound for element 30 is 30 located at position 2 
The upper bound for element 30 is 40 located at position 3
Input: set[] = {10, 20, 30, 40, 50, 60}, K = 60 
Output: 
Lower Bound of 60: 5
Upper Bound of 60: -1 



Approach: 

Below is the implementation of lower_bound() and upper_bound():




// C++ program to implement the
// lower_bound() and upper_bound()
// using Ordered Set
 
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
 
// Ordered Set Tree
typedef tree<int, null_type, less<int>, rb_tree_tag,
             tree_order_statistics_node_update>
    ordered_set;
 
ordered_set set1;
 
// Function that returns the lower bound
// of the element
int lower_bound(int x)
{
    // Finding the position of the element
    int pos = set1.order_of_key(x);
 
    // If the element is not present in the set
    if (pos == set1.size())
    {
        return -1;
    }
 
    // Finding the element at the position
    else
    {
        int element = *(set1.find_by_order(pos));
 
        return element;
    }
}
 
// Function that returns the upper bound
// of the element
int upper_bound(int x)
{
    // Finding the position of the element
    int pos = set1.order_of_key(x + 1);
 
    // If the element is not present
    if (pos == set1.size())
    {
        return -1;
    }
 
    // Finding the element at the position
    else
    {
        int element = *(set1.find_by_order(pos));
 
        return element;
    }
}
 
// Function to print Upper
// and Lower bound of K
// in Ordered Set
void printBound(int K)
{
 
    cout << "Lower Bound of " << K << ": " << lower_bound(K)
         << endl;
    cout << "Upper Bound of " << K << ": " << upper_bound(K)
         << endl;
}
 
// Driver's Code
int main()
{
    set1.insert(10);
    set1.insert(20);
    set1.insert(30);
    set1.insert(40);
    set1.insert(50);
 
    int K = 30;
    printBound(K);
 
    K = 60;
    printBound(K);
 
    return 0;
}

Output
Lower Bound of 30: 30
Upper Bound of 30: 40
Lower Bound of 60: -1
Upper Bound of 60: -1

Time Complexity: O(log N)
Auxiliary Space: O(1)


Article Tags :