Order statistic tree using fenwick tree (BIT)
Last Updated :
08 Mar, 2023
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 Tree
The 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++
#include <bits/stdc++.h>
using namespace std;
const int MAX_VAL = 1000001;
void update( int i, int add, vector< int >& BIT)
{
while (i > 0 && i < BIT.size())
{
BIT[i] += add;
i = i + (i & (-i));
}
}
int sum( int i, vector< int >& BIT)
{
int ans = 0;
while (i > 0)
{
ans += BIT[i];
i = i - (i & (-i));
}
return ans;
}
int findKthSmallest( int k, vector< int > &BIT)
{
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;
}
void insertElement( int x, vector< int > &BIT)
{
update(x, 1, BIT);
}
void deleteElement( int x, vector< int > &BIT)
{
update(x, -1, BIT);
}
int findRank( int x, vector< int > &BIT)
{
return sum(x, BIT);
}
int 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
import java.util.Arrays;
class GFG{
static int MAX_VAL = 1000001 ;
static void update( int i, int add,
Integer[] BIT)
{
while (i > 0 && i < BIT.length)
{
BIT[i] += add;
i = i + (i & (-i));
}
}
static int sum( int i, Integer[] BIT)
{
int ans = 0 ;
while (i > 0 )
{
ans += BIT[i];
i = i - (i & (-i));
}
return ans;
}
static int findKthSmallest( int k,
Integer[] BIT)
{
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;
}
static void insertElement( int x, Integer[] BIT)
{
update(x, 1 , BIT);
}
static void deleteElement( int x, Integer[] BIT)
{
update(x, - 1 , BIT);
}
static int findRank( int x, Integer[] BIT)
{
return sum(x, BIT);
}
public 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));
}
}
|
Python3
from typing import List
MAX_VAL = 1000001
def update(i: int , add: int , BIT: List [ int ]) - > None :
while i > 0 and i < len (BIT):
BIT[i] + = add
i = i + (i & ( - i))
def sum (i: int , BIT: List [ int ]) - > int :
ans = 0
while i > 0 :
ans + = BIT[i]
i = i - (i & ( - i))
return ans
def find_kth_smallest(k: int , BIT: List [ int ]) - > int :
l = 0
h = len (BIT)
while l < h:
mid = (l + h) / / 2
if k < = sum (mid, BIT):
h = mid
else :
l = mid + 1
return l
def insert_element(x: int , BIT: List [ int ]) - > None :
update(x, 1 , BIT)
def delete_element(x: int , BIT: List [ int ]) - > None :
update(x, - 1 , BIT)
def find_rank(x: int , BIT: List [ int ]) - > int :
return sum (x, BIT)
BIT = [ 0 ] * MAX_VAL
insert_element( 20 , BIT)
insert_element( 50 , BIT)
insert_element( 30 , BIT)
insert_element( 40 , BIT)
print (f "2nd Smallest element is {find_kth_smallest(2, BIT)}" )
print (f "Rank of 40 is {find_rank(40, BIT)}" )
delete_element( 40 , BIT)
print (f "Rank of 50 is {find_rank(50, BIT)}" )
|
Javascript
const MAX_VAL = 1000001;
function update(i, add, BIT) {
while (i > 0 && i < BIT.length) {
BIT[i] += add;
i = i + (i & (-i));
}
}
function sum(i, BIT) {
let ans = 0;
while (i > 0) {
ans += BIT[i];
i = i - (i & (-i));
}
return ans;
}
function findKthSmallest(k, BIT) {
let l = 0;
let h = BIT.length;
while (l < h) {
let mid = Math.floor((l + h) / 2);
if (k <= sum(mid, BIT)) {
h = mid;
} else {
l = mid + 1;
}
}
return l;
}
function insertElement(x, BIT) {
update(x, 1, BIT);
}
function deleteElement(x, BIT) {
update(x, -1, BIT);
}
function findRank(x, BIT) {
return sum(x, BIT);
}
let BIT = new Array(MAX_VAL).fill(0);
insertElement(20, BIT);
insertElement(50, BIT);
insertElement(30, BIT);
insertElement(40, BIT);
console.log(`2nd Smallest element is ${findKthSmallest(2, BIT)}`);
console.log(`Rank of 40 is ${findRank(40, BIT)}`);
deleteElement(40, BIT);
console.log(`Rank of 50 is ${findRank(50, BIT)}`);
|
C#
using System;
using System.Collections.Generic;
public class GFG{
const int MAX_VAL = 1000001;
static void Update( int i, int add, int [] BIT)
{
while (i > 0 && i < BIT.Length)
{
BIT[i] += add;
i = i + (i & (-i));
}
}
static int Sum( int i, int [] BIT)
{
int ans = 0;
while (i > 0)
{
ans += BIT[i];
i = i - (i & (-i));
}
return ans;
}
static int FindKthSmallest( int k, int [] BIT)
{
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;
}
static void InsertElement( int x, int [] BIT)
{
Update(x, 1, BIT);
}
static void DeleteElement( int x, int [] BIT)
{
Update(x, -1, BIT);
}
static int FindRank( int x, int [] BIT)
{
return Sum(x, BIT);
}
static void Main( string [] args)
{
int [] BIT = new int [MAX_VAL];
InsertElement(20, BIT);
InsertElement(50, BIT);
InsertElement(30, BIT);
InsertElement(40, BIT);
Console.WriteLine( "2nd Smallest element is " + FindKthSmallest(2, BIT));
Console.WriteLine( "Rank of 40 is " + FindRank(40, BIT));
DeleteElement(40, BIT);
Console.WriteLine( "Rank of 50 is " + FindRank(50, BIT));
}
}
|
Output:
2nd Smallest element is 30
Rank of 40 is 3
Rank of 50 is 3
Time Complexity:- O(log N)
Space Complexity:- O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...