Order statistic tree using fenwick tree (BIT) - GeeksforGeeks

20 Nov, 2020
Given an array of integers with limited range (0 to 1000000). We need to implement an Order statistic tree using fenwick tree. It should support four operations: Insert, Delete, Select and Rank. Here n denotes the size of Fenwick tree and q denotes number of queries. 
Each query should be one of the following 4 operations. 
insertElement(x) – Insert element x into Fenwick tree, with O(log n) worst case time complexity
deleteElement(x) – Delete element x from fenwick tree, with O(log n) worse case time complexity
findKthSmallest(k) – Find the k-th smallest element stored in the tree, with O(log n * log n) worst case time complexity
findRank(x) – Find the rank of element x in the tree, i.e. its index in the sorted list of elements of the tree, with O(log n) time complexity
Prerequisite: Binary Indexed Tree or Fenwick TreeThe idea is to create a BIT of size with maximum limit. We insert an element in BIT using it as an index. When we insert an element x, we increment values of all ancestors of x by 1. To delete an element, we decrement values of ancestors by 1. We basically call standard function update() of BIT for both insert and delete. To find rank, we simply call standard function sum() of BIT. To find k-th smallest element, we do binary search in BIT.
C++
Java
// C++ program to find rank of an element// and k-th smallest element.#include <bits/stdc++.h>using namespace std; const int MAX_VAL = 1000001; /* Updates element at index 'i' of BIT. */void update(int i, int add, vector<int>& BIT){    while (i > 0 && i < BIT.size())    {        BIT[i] += add;        i = i + (i & (-i));    }} /* Returns cumulative sum of all elements of   fenwick tree/BIT from start upto and   including element at index 'i'. */int sum(int i, vector<int>& BIT){    int ans = 0;    while (i > 0)    {        ans += BIT[i];        i = i - (i & (-i));    }     return ans;} // Returns lower bound for k in BIT.int findKthSmallest(int k, vector<int> &BIT){    // Do binary search in BIT[] for given    // value k.    int l = 0;    int h = BIT.size();    while (l < h)    {        int mid = (l + h) / 2;        if (k <= sum(mid, BIT))            h = mid;        else            l = mid+1;    }     return l;} // Insert x into BIT. We basically increment// rank of all elements greater than x.void insertElement(int x, vector<int> &BIT){    update(x, 1, BIT);} // Delete x from BIT. We basically decreases// rank of all elements greater than x.void deleteElement(int x, vector<int> &BIT){    update(x, -1, BIT);} // Returns rank of element. We basically// return sum of elements from start to// index x.int findRank(int x, vector<int> &BIT){    return sum(x, BIT);} // Driver codeint main(){    vector<int> BIT(MAX_VAL);    insertElement(20, BIT);    insertElement(50, BIT);    insertElement(30, BIT);    insertElement(40, BIT);     cout << "2nd Smallest element is "     << findKthSmallest(2, BIT) << endl;     cout << "Rank of 40 is "         << findRank(40, BIT) << endl;     deleteElement(40, BIT);     cout << "Rank of 50 is "         << findRank(50, BIT) << endl;     return 0;}
// Java program to find rank of an element// and k-th smallest element.import java.util.Arrays; class GFG{ static int MAX_VAL = 1000001; // Updates element at index 'i' of BITstatic void update(int i, int add,                   Integer[] BIT){    while (i > 0 && i < BIT.length)    {        BIT[i] += add;        i = i + (i & (-i));    }} // Returns cumulative sum of all elements// of fenwick tree/BIT from start upto// and including element at index 'i'.static int sum(int i, Integer[] BIT){    int ans = 0;    while (i > 0)    {        ans += BIT[i];        i = i - (i & (-i));    }    return ans;} // Returns lower bound for k in BIT.static int findKthSmallest(int k,                           Integer[] BIT){         // Do binary search in BIT[]    // for given value k.    int l = 0;    int h = BIT.length;         while (l < h)    {        int mid = (l + h) / 2;        if (k <= sum(mid, BIT))            h = mid;        else            l = mid + 1;    }    return l;} // Insert x into BIT. We basically// increment rank of all elements// greater than x.static void insertElement(int x, Integer[] BIT){    update(x, 1, BIT);} // Delete x from BIT. We basically// decreases rank of all elements// greater than x.static void deleteElement(int x, Integer[] BIT){    update(x, -1, BIT);} // Returns rank of element. We basically// return sum of elements from start to// index x.static int findRank(int x, Integer[] BIT){    return sum(x, BIT);} // Driver codepublic static void main(String[] args){    Integer[] BIT = new Integer[MAX_VAL];      Arrays.fill(BIT, 0);           insertElement(20, BIT);    insertElement(50, BIT);    insertElement(30, BIT);    insertElement(40, BIT);     System.out.println("2nd Smallest element is " +                        findKthSmallest(2, BIT));    System.out.println("Rank of 40 is " +                        findRank(40, BIT));     deleteElement(40, BIT);         System.out.println("Rank of 50 is " +                        findRank(50, BIT));}} // This code is contributed by sanjeev2552
Output: 
2nd Smallest element is 30
Rank of 40 is 3
Rank of 50 is 3


If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks. 
kapillamba4
albertoottimo
sanjeev2552
BIT
Order-Statistics
Advanced Data Structure
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Ordered Set and GNU C++ PBDS
2-3 Trees | (Search, Insert and Deletion)
Extendible Hashing (Dynamic approach to DBMS)
Suffix Array | Set 1 (Introduction)
Difference between Backtracking and Branch-N-Bound technique
Quad Tree
Advantages of Trie Data Structure
Implement a Phone Directory
String hashing using Polynomial rolling hash function