Best Data Structure/Algorithm for insert/delete/rank/select queries

淺唱寂寞╮ 提交于 2019-12-03 09:37:29

As mentioned in the comments, if you want to maintain a set of integers and you can do a coordinate compression as a preprocessing step (e.g. because your algorithm is offline and knows all the future queries), you can use a binary-indexed tree to support insert/delete/rank/select of numbers in O(log n) per operation. Here's an example in C++:

int tree[N];  // where N is the number of compressed coordinates
const int maxl = floor(log(N)/log(2));

void insert(int i) { // 1 <= i <= N
  for (; i <= N; i += i & -i) ++tree[i];
}

void remove(int i) { // 1 <= i <= N
  for (; i <= N; i += i & -i) --tree[i];
}

int rank(int i) { // 1 <= i <= N
  int sum = 0;
  for (; i; i -= i & -i) sum += tree[i];
  return sum;
}

int select(int k) { // k is 1-based
  int ans = 0, s = 0;
  for (int i = maxl; i >= 0; --i) // maxl = largest i s.t. (1<<i) <= N
    if (s + tree[ans + (1<<i)] < k) {
      ans += 1<<i;
      s += tree[ans];
    }
  return ans+1;
}

The select function is somewhat magical. It reuses the results from higher bits to compute the prefix sum of ans + (1<<i) in O(1), which is pretty cool IMHO :) This way it only takes time O(log n), instead of the O(log^2 n) that is easy to achieve using a standard binary search.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!