给定整数范围有限的整数(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