Hey everyone!
I recently built a neat wrapper around GNU PBDS's ordered multiset to simplify operations like:
- Counting how many elements are <, <=, >, or >= a value
- Range frequency queries like [l, r], (l, r], etc.
- Accessing the k-th smallest element (0-based) with [] operator
It's named SortedArray, and it makes these operations intuitive using operator overloading.
Use the code below and make sure you have ordered_set included from PBDS,
class SortedArray {
ordered_multiset arr;
public:
long long size() { return arr.size(); }
void operator += (long long x) { arr.insert(x); }
long long operator < (long long x) { return arr.order_of_key(x); }
long long operator <= (long long x) { return arr.order_of_key(x+1); }
long long operator > (long long x) { return arr.size() - arr.order_of_key(x+1); }
long long operator >= (long long x) { return arr.size() - arr.order_of_key(x); }
long long LR(long long l, long long r) { return max((*this <= r) - (*this < l), 0LL); }
long long lR(long long l, long long r) { return LR(l+1, r); }
long long Lr(long long l, long long r) { return LR(l, r-1); }
long long lr(long long l, long long r) { return LR(l+1, r-1); }
long long operator [] (long long i) { return *arr.find_by_order(i); }
};
Here’s how it works in practice:
SortedArray sa;
sa += 5;
sa += 10;
sa += 5;
cout << sa.size() << "\n"; // 3
cout << (sa < 6) << "\n"; // 2 (number of elements < 6)
cout << (sa <= 5) << "\n"; // 2
cout << (sa > 5) << "\n"; // 1
cout << (sa >= 10) << "\n"; // 1
cout << sa[1] << "\n"; // 5 (element at index 1)
cout << sa.LR(5, 10) << "\n"; // 3 (in [5, 10])
cout << sa.lR(5, 10) << "\n"; // 1 (in (5, 10])
cout << sa.Lr(5, 10) << "\n"; // 2 (in [5, 10))
cout << sa.lr(5, 10) << "\n"; // 0 (in (5, 10))
Let me know what you think! Hope it helps you




