Range Module in C++


Suppose we want a Range Module. This is a module that tracks ranges of numbers. Our task is to design and implement the following interfaces in an efficient manner.

  • addRange(left, right). This will the half-open interval [left, right), tracking every real number in that interval. Now, adding an interval that partially overlaps with currently tracked numbers should add any numbers in the interval that are not already tracked.
  • queryRange(left, right) . This will return true when every real number in the interval [left, right) is currently being tracked.
  • removeRange(left, right), this will stop tracking every real number currently being tracked in the interval [left, right).

To solve this, we will follow these steps −

  • Define one map m
  • Define a function addRange(), this will take left, right,
  • removeRange(left, right)
  • m[left] := right
  • it := location where left is present in m
  • if it is not equal to first element of m and second value of of previous of it is same as left, then −
    • (decrease it by 1)
    • second of it := right
    • delete left from m
  • if it is not equal to previous of last element of m and first of next of it is same as right, then −
    • second of it := second of next(it)
    • delete next(it) from m
  • Define a function queryRange(), this will take left, right,
  • it := location of a subpart of m all smaller value than left
  • if m is empty or it is same as first element of m, then −
    • return false
  • (decrease it by 1)
  • return true when second of it >= right
  • Define a function removeRange(), this will take left, right,
  • if m is empty, then −
    • return
  • it := location of a subpart of m all upper value than left
  • if it is not equal to first element of m, then −
    • (decrease it by 1)
  • Define an array v
  • while (it is not equal to last element of m and first of it < right), do −
    • if first of it < left and second of it > left, then −
      • temp := second of it
      • second of it := left
      • if temp > right, then: m[right] := temp
    • otherwise when first of it >= left, then −
      • Insert first of it at the end of v
      • if second of it > right, then −
        • m[right] := second of it
    • (increase it by 1)
  • for initialize i := 0, when i < size of v, update (increase i by 1), do −
    • delete v[i] from m

Let us see the following implementation to get better understanding −

Example

 Live Demo

#include <bits/stdc++.h>
using namespace std;
class RangeModule {
public:
   map <int, int> m;
   RangeModule() {
   }
   void addRange(int left, int right) {
      removeRange(left, right);
      m[left] = right;
      map <int, int> :: iterator it = m.find(left);
      if(it != m.begin() && prev(it)->second == left){
         it--;
         it->second = right;
         m.erase(left);
      }
      if(it != prev(m.end()) && next(it)->first == right){
         it->second = next(it)->second;
         m.erase(next(it));
      }
   }
   bool queryRange(int left, int right) {
      map <int, int> :: iterator it = m.upper_bound(left);
      if(m.empty() || it == m.begin())return false;
      it--;
      return it->second >= right;
   }
   void removeRange(int left, int right) {
      if(m.empty())return;
      map <int, int> :: iterator it = m.lower_bound(left);
      if(it != m.begin())it--;
      vector <int> v;
      while(it != m.end() && it->first < right){
         if(it->first < left && it->second > left){
            int temp = it->second;
            it->second = left;
            if(temp > right){
               m[right] = temp;
            }
         }else if(it->first >= left){
            v.push_back(it->first);
            if(it->second > right){
               m[right] = it->second;
            }
         }
         it++;
      }
      for(int i = 0; i < v.size(); i++){
         m.erase(v[i]);
      }
   }
};
main(){
   RangeModule ob;
   ob.addRange(10,20);
   ob.removeRange(14,16);
   cout << (ob.queryRange(10,14)) << endl;
   cout << (ob.queryRange(13,15)) << endl;
   cout << (ob.queryRange(16,17));
}

Input

Add range (10,20)
Remove Range (14,16)
Check ranges (10,14), (13,15), (16,17)

Output

1
0
1

Updated on: 02-Jun-2020

175 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements