This repository has been archived on 2022-06-22. You can view files and clone it, but cannot push or open issues or pull requests.
usaco-guide/content/5_Gold/BIT.md
Benjamin Qi 7cbdfba674 a bunch
2020-06-15 21:44:03 -04:00

4.2 KiB

id title author prerequisites
bit Binary Indexed Trees Benjamin Qi
Silver - Prefix Sums

A Binary Indexed Tree allows you to perform the following tasks in O(\log N) time each on an array of size N:

  • Update the element at a single position (point).
  • Query the sum of a prefix of the array.

Binary Indexed Tree

Aka Fenwick Tree.

Sample Problems

Tutorials

My implementation can be found here, and can compute range sum queries for any number of dimensions.

Indexed Set

In the special case where all elements of the array are either zero or one (which is the case for several gold problems), users of C++ will find indexed set useful. Using this, we can solve "Inversion Counting" in just a few lines (with template). Tree<int> behaves mostly the same way as set<int> with the additional functions

  • order_of_key(x): counts the number of elements in the indexed set that are strictly less than x.
  • find_by_order(k): similar to find, returns the iterator corresponding to the k-th lowest element in the set (0-indexed).

See the link for more examples of usage.

#include <bits/stdc++.h>
using namespace std;

#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
template <class T> using Tree = tree<T, null_type, less<T>, 
  rb_tree_tag, tree_order_statistics_node_update>; 

int main() {
  int T; cin >> T;
  for (int i = 0; i < T; ++i) {
    int n; cin >> n;
    Tree<int> TS; long long numInv = 0;
    for (int j = 0; j < n; ++j) { 
      int x; cin >> x;
      numInv += j-TS.order_of_key(x); // gives # elements before it > x
      TS.insert(x);
    }
    cout << numInv << "\n";
  }
}

Note that if it were not the case that all elements of the input array were distinct, then this code would be incorrect since Tree<int> would remove duplicates. Instead, we would use an indexed set of pairs (Tree<pair<int,int>>), where the first element of each pair would denote the value while the second would denote the array position.

Practice Problems