Open In App

How to Store Duplicate Elements in Ordered Set in C++?

Last Updated : 19 May, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Ordered Set contains UNIQUE elements in sorted order just like set. While dealing with an ordered set with duplicate elements, the pair<int, int> data type is used instead of int where the first value of the pair will store the element and the second value will store the corresponding indexes. By doing this each pair in the ordered set will be unique and one can easily store the duplicate elements of the array.

Operations:

1. order_of_key(): It accepts an element as a parameter and returns the number of elements strictly less than the key. While implementing it, we need to pass a pair as the parameter whose first value needs to be the number which we want the result for and the second value will contain a negative value e.g., -1 because the inserted pairs in the ordered_set will have the value greater than equal to 0 as it denotes the indexes of the array.

2. find_by_order(): It accepts an index as a parameter and returns an iterator to the ith element (pair) in sorted order. 

Example:

Let assume there is a ordered set pair mySet = {4, 7, 2, 4, 5, 8, 4, 1, 3, 5}

Here,

  • The ordered set pair has duplicate elements.
  • After inserting all elements in ordered_set_pair,
  • mySet.order_of_key({5, -1}): It will give the number of elements less than 5 i.e, 6.
  • mySet.find_by_order(8): It will give an iterator to 8th element in the ordered set i.e, 7.

Below is the C++ program to implement the above approach:

C++




// C++ program to store duplicate 
// elements in ordered set
#include <bits/stdc++.h>
using namespace std;
  
// Header files to implement ordered set
// Common file
#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp>
  
// namespace necessary for GNU based 
// policy based data structures
using namespace __gnu_pbds;
  
  
// Declaring ordered_set for pair<int,int>
typedef tree<pair<int,int>, null_type, 
        less<pair<int,int>>, rb_tree_tag,
        tree_order_statistics_node_update>
        ordered_set_pair;
  
// Driver code
int main()
{
      int arr[10] = {4, 7, 2, 4, 5, 
                   8, 4, 1, 3, 5};
      ordered_set_pair mySet;
    
      // Inserting elements to 
    // ordered_set_pair
      for(int i = 0; i < 10; i++)
    {
          mySet.insert({arr[i], i});
    }
  
    // count of elements less than 5
    cout << "Count of elements less than 5: " << 
             mySet.order_of_key({5, -1}) << endl;
  
    // Print 8th element in the ordered set
    // iterator to a pair
      auto itr = mySet.find_by_order(8); 
      cout << "The 8th element in the ordered set is: " << 
             (*itr).first << endl;
    return 0;
}


Output

Count of elements less than 5: 6
The 8th element in the ordered set is: 7

For range queries like the number of elements lying between L and R inclusive i.e., [L, R], one can find it using:

mySet.order_of_key({R+1,-1}) – myset.order_of_key({L,-1}) 

Time complexity for both the operations i.e., find_by_order() and order_of_key() is O(log(n)).



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads