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/3_Gold/5_Gold_BIT.md
2020-06-04 10:20:28 -04:00

4.3 KiB

slug title author order
/gold/bit Binary Indexed Trees Benjamin Qi 5
Description: Todo

Prerequisites

Assumes that you are familiar with prefix sum queries (CPH 9.1).

Task

Given an array of size N, the task is to update the element at a single position (point) in addition to querying the sum of a prefix in O(\log N) time each.

Sample Problems:

Binary Indexed Tree

Probably the easiest way to do all of these tasks (aka Fenwick Tree).

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