4.9 KiB
Gold - 1D Range Queries
Author: Benjamin Qi
Prerequisites
Assumes that you are familiar with prefix sum queries (CPH 9.1).
Binary Indexed Tree
Introduction
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:
- CSES Range Sum Queries II
- CSES Range XOR Queries
- essentially the same as above
- SPOJ Inversion Counting
The easiest way to do all of these tasks is with a Binary Indexed Tree (or Fenwick Tree).
Tutorials:
- CPH 9.2 (very good)
- CSAcademy BIT (also very good)
- cp-algorithms Fenwick Tree
- extends to range increment and range query, although this is not necessary for gold
- Topcoder BIT
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 function order_of_key(x)
, which
counts the number of elements in the indexed set that are strictly less than x
. See the link for more examples of usage.
#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>;
#define ook order_of_key
#define fbo find_by_order
int main() {
setIO();
int T; re(T);
F0R(i,T) {
int n; re(n);
Tree<int> T; ll numInv = 0;
F0R(j,n) {
int x; re(x);
numInv += j-T.ook(x); // gives # elements before it > x
T.insert(x);
}
ps(numInv);
}
}
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
- USACO Gold
- The first three problems are just variations on inversion counting.
- Haircut
- Balanced Photo
- Circle Cross
- Sleepy Cow Sort
- as far as I know, all gold problems have had only one possible output ...
- Out of Sorts (harder?)
- Other Problems:
- Mega Inversions
- also just inversion counting
- Out of Sorts (USACO Silver)
- aka Sorting Steps
- Of course, this doesn't require anything other than sorting but fast range sum queries may make this easier.
- Mega Inversions
Beyond Summation
The following topics have not been required for gold (so far).
Static Range Queries
- Range Minimum Query??
- Tutorial
- Wikipedia
- (add)
- Tutorial
- Static range queries in
O(1)
time andO(N\log N)
preprocessing for any associative operation?- (add)
Segment Tree
This data structure allows you to do point update and range query in O(\log N)
time each for any associative operation.
- Tutorial
- Problems
- USACO Springboards
- can use segment tree with min query in place of the map mentioned in analysis
- POI Cards
- Counting Haybales (USACO Plat)
- Lazy Updates
- USACO Springboards