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

后端 未结 1 640
星月不相逢
星月不相逢 2021-02-11 00:17

So far, I know that self-balancing BST like AVL tree and Red Black Tree can do these operations in O(log n) times.

However, to use these structures, we must implement AV

相关标签:
1条回答
  • 2021-02-11 00:54

    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.

    0 讨论(0)
提交回复
热议问题