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/6_Gold_BIT.md

92 lines
4.2 KiB
Markdown
Raw Normal View History

2020-06-03 22:18:17 +00:00
---
slug: /gold/bit
2020-06-04 05:39:49 +00:00
title: "Binary Indexed Trees"
2020-06-04 01:42:57 +00:00
author: Benjamin Qi
2020-06-05 00:21:03 +00:00
order: 6
prerequisites:
-
- Silver - Prefix Sums
2020-06-03 22:18:17 +00:00
---
2020-06-04 21:42:30 +00:00
A **Binary Indexed Tree** allows you to perform the following tasks in $O(\log N)$ time each on an array of size $N$:
2020-06-03 03:18:02 +00:00
2020-06-04 14:28:47 +00:00
- Update the element at a single position (point).
- Querying the sum of a prefix of the array.
2020-06-03 03:18:02 +00:00
2020-06-04 14:28:47 +00:00
<!-- END DESCRIPTION -->
2020-06-03 03:18:02 +00:00
2020-06-04 14:28:47 +00:00
## Binary Indexed Tree
2020-06-03 03:18:02 +00:00
2020-06-04 21:42:30 +00:00
Aka **Fenwick Tree**.
2020-06-03 03:18:02 +00:00
2020-06-04 14:28:47 +00:00
### Sample Problems
2020-06-03 03:18:02 +00:00
* [CSES Range Sum Queries II](https://cses.fi/problemset/task/1648)
2020-06-03 20:16:33 +00:00
* can also do range XOR queries w/ update
2020-06-03 03:18:02 +00:00
* [SPOJ Inversion Counting](https://www.spoj.com/problems/INVCNT/)
2020-06-04 14:28:47 +00:00
### Tutorials
2020-06-03 03:18:02 +00:00
2020-06-03 03:42:17 +00:00
* CPH 9.2 (very good)
2020-06-03 03:18:02 +00:00
* [CSAcademy BIT](https://csacademy.com/lesson/fenwick_trees) (also very good)
* [cp-algorithms Fenwick Tree](https://cp-algorithms.com/data_structures/fenwick.html)
2020-06-03 03:42:17 +00:00
* extends to range increment and range query, although this is not necessary for gold
2020-06-03 03:18:02 +00:00
* [Topcoder BIT](https://www.topcoder.com/community/data-science/data-science-tutorials/binary-indexed-trees/)
My implementation can be found [here](https://github.com/bqi343/USACO/blob/master/Implementations/content/data-structures/1D%20Range%20Queries%20(9.2)/BIT%20(9.2).h), and can compute range sum queries for any number of dimensions.
2020-06-03 14:17:07 +00:00
## Indexed Set
2020-06-03 03:18:02 +00:00
2020-06-03 14:17:07 +00:00
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](https://github.com/bqi343/USACO/blob/master/Implementations/content/data-structures/STL%20(5)/IndexedSet.h) 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.
2020-06-03 03:18:02 +00:00
```cpp
2020-06-03 14:17:07 +00:00
#include <bits/stdc++.h>
using namespace std;
2020-06-03 03:18:02 +00:00
#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>,
2020-06-03 03:42:17 +00:00
rb_tree_tag, tree_order_statistics_node_update>;
2020-06-03 03:18:02 +00:00
int main() {
2020-06-03 14:17:07 +00:00
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);
2020-06-03 03:42:17 +00:00
}
2020-06-03 14:17:07 +00:00
cout << numInv << "\n";
2020-06-03 03:42:17 +00:00
}
2020-06-03 03:18:02 +00:00
}
```
2020-06-03 03:56:59 +00:00
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.
2020-06-03 14:17:07 +00:00
## Practice Problems
2020-06-03 03:18:02 +00:00
* USACO Gold
2020-06-03 03:42:17 +00:00
* The first three problems are just variations on inversion counting.
2020-06-03 03:18:02 +00:00
* [Haircut](http://www.usaco.org/index.php?page=viewproblem2&cpid=1041)
* [Balanced Photo](http://www.usaco.org/index.php?page=viewproblem2&cpid=693)
* [Circle Cross](http://www.usaco.org/index.php?page=viewproblem2&cpid=719)
* [Sleepy Cow Sort](http://usaco.org/index.php?page=viewproblem2&cpid=898)
2020-06-03 03:42:17 +00:00
* as far as I know, all gold problems have had only one possible output ...
2020-06-03 03:18:02 +00:00
* [Out of Sorts (harder?)](http://www.usaco.org/index.php?page=viewproblem2&cpid=837)
* Other Problems:
2020-06-04 03:26:53 +00:00
* [USACO Plat Mincross](http://www.usaco.org/index.php?page=viewproblem2&cpid=720)
2020-06-03 03:42:17 +00:00
* [Mega Inversions](https://open.kattis.com/problems/megainversions)
* also just inversion counting
* [Out of Sorts (USACO Silver)](http://usaco.org/index.php?page=viewproblem2&cpid=834)
* aka [Sorting Steps](https://csacademy.com/contest/round-42/task/sorting-steps/) [](42)
2020-06-04 03:26:53 +00:00
* Of course, this doesn't require anything other than sorting but fast range sum queries may make this easier.
* [Twin Permutations](https://www.hackerearth.com/practice/data-structures/advanced-data-structures/fenwick-binary-indexed-trees/practice-problems/algorithm/mancunian-and-twin-permutations-d988930c/description/)
2020-06-08 19:51:58 +00:00
* Offline 2D queries can be done with a 1D data structure