📜  使用fenwick树(BIT)的订单统计树

📅  最后修改于: 2021-04-17 08:21:30             🧑  作者: Mango

给定整数范围有限的整数(0到1000000)。我们需要使用fenwick树实现Order统计树。
它应该支持四种操作:插入,删除,选择和排序。在此,n表示分域树的大小,q表示查询数。

每个查询应为以下4个操作之一。

  • insertElement(x)–将元素x插入Fenwick树中,最坏情况下的时间复杂度为O(log n)
  • deleteElement(x)–从fenwick树中删除元素x,O(log n)的情况更糟,时间复杂度
  • findKthSmallest(k)–查找存储在树中的第k个最小元素,O(log n * log n)最坏情况下的时间复杂度
  • findRank(x)–在树中找到元素x的等级,即在树的元素排序列表中的索引,时间复杂度为O(log n)

先决条件:二叉索引树或Fenwick树
这个想法是创建一个具有最大限制的大小的BIT。我们使用BIT作为索引在BIT中插入一个元素。当我们插入元素x时,我们将x的所有祖先的值增加1。要删除元素,我们将祖先的值减小1。我们基本上为插入和删除调用BIT的标准函数update()。要找到排名,我们只需调用BIT的标准函数sum()即可。为了找到第k个最小元素,我们在BIT中进行二进制搜索。

C++
// C++ program to find rank of an element
// and k-th smallest element.
#include 
using namespace std;
 
const int MAX_VAL = 1000001;
 
/* Updates element at index 'i' of BIT. */
void update(int i, int add, vector& 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& 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 &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 &BIT)
{
    update(x, 1, BIT);
}
 
// Delete x from BIT. We basically decreases
// rank of all elements greater than x.
void deleteElement(int x, vector &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 &BIT)
{
    return sum(x, BIT);
}
 
// Driver code
int main()
{
    vector 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
// 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 BIT
static 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 code
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));
}
}
 
// This code is contributed by sanjeev2552


输出:

2nd Smallest element is 30
Rank of 40 is 3
Rank of 50 is 3