Table of Contents
2D RMQ2D BITTutorialImplementationAlternative ImplementationProblems2D Offline Sum QueriesSolution - Soriya's Programming ProjectIdea 1: Use an unordered map instead of a 2D array.Idea 2: Compress the points to be updated so that you only need \mathcal{O}(N\log N) memory.Idea 3: Use divide & conquer with a 1D BITProblems2D Segment TreeImplementationNote - Memory UsageProblemsEdit on Github2D Range Queries
Authors: Benjamin Qi, Andi Qu
Prerequisites
Extending Range Queries to 2D (and beyond).
Table of Contents
2D RMQ2D BITTutorialImplementationAlternative ImplementationProblems2D Offline Sum QueriesSolution - Soriya's Programming ProjectIdea 1: Use an unordered map instead of a 2D array.Idea 2: Compress the points to be updated so that you only need \mathcal{O}(N\log N) memory.Idea 3: Use divide & conquer with a 1D BITProblems2D Segment TreeImplementationNote - Memory UsageProblemsEdit on Github
2D RMQ
Resources | |||
---|---|---|---|
CF |
Quite rare, I've only needed this once.
2D BIT
Focus Problem – read through this problem before continuing!
Tutorial
Resources | |||
---|---|---|---|
GFG | |||
TC |
Implementation
Essentially, we just nest the loops that one would find in a 1D BIT to get N-dimensional BITs. We can then use PIE to query subrectangles.
C++
1#include <bits/stdc++.h>2using namespace std;34int bit[1001][1001];5int n;67void update(int x, int y, int val) {8 for (; x <= n; x += (x & (-x))) {9 for (int i = y; i <= n; i += (i & (-i))) {10 bit[x][i] += val;
Alternative Implementation
Using the multidimensional implementation mentioned here.
1template <class T, int ...Ns> struct BIT {2 T val = 0;3 void upd(T v) { val += v; }4 T query() { return val; }5};67template <class T, int N, int... Ns> struct BIT<T, N, Ns...> {8 BIT<T,Ns...> bit[N + 1];9 template<typename... Args> void upd(int pos, Args... args) {10 for (; pos <= N; pos += (pos&-pos)) bit[pos].upd(args...);
Problems
Status | Source | Problem Name | Difficulty | Tags | Solution | URL |
---|---|---|---|---|---|---|
DMOJ | Normal | Show Tags2D, BIT | Check DMOJ | |||
IOI | Normal | Show Tags3D, BIT | External Sol |
Lazy propagation on segment trees does not extend to higher dimensions. However, you can extend the 1D BIT solution to solve range increment range sum in higher dimensions as well! See this paper for details.
- USACO Camp - "Cows Play Global Thermonuclear War" (2D case)
2D Offline Sum Queries
See my implementations.
Focus Problem – read through this problem before continuing!
The intended complexity is with a good constant factor. This requires updating points and querying rectangle sums times for points with coordinates in the range . However, the 2D BITs mentioned above use memory, which is too much.
Solution - Soriya's Programming Project
Since we know all of the updates and queries beforehand, we can reduce the memory usage while maintaining a decent constant factor.
Idea 1: Use an unordered map instead of a 2D array.
Bad idea ... This gives memory and time and the constant factors for both are terrible.
Idea 2: Compress the points to be updated so that you only need memory.
This doesn't require knowing the queries beforehand.
It's a bit difficult to pass the above problem within the time limit. Make sure to use fast input (and not endl
)!
Idea 3: Use divide & conquer with a 1D BIT
The fastest way.
- mentioned in this article
- thecodingwizard's (messy) implementation based off above
Problems
Status | Source | Problem Name | Difficulty | Tags | Solution | URL |
---|---|---|---|---|---|---|
Plat | Normal | Show Tags2D, BIT | ||||
Plat | Normal | Show Tags2D, BIT | External Sol | |||
APIO | Normal | Show Tags2D, BIT | View Solution |
2D Segment Tree
A segment tree of (maybe sparse) segment trees.
Pro Tip
This is not the same as Quadtree. If the coordinates go up to , then 2D segment tree queries run in time each but some queries make Quadtree take time!
Resources | |||
---|---|---|---|
CPH | Brief description |
Implementation
Resources | |||
---|---|---|---|
USACO | Code | ||
cp-algo | More code |
Note - Memory Usage
Naively, inserting elements into a sparse segment tree requires memory, giving a bound of on 2D segment tree memory. This is usually too much for and 256 MB (although it sufficed for "Mowing the Field" due to the 512MB memory limit). Possible ways to get around this:
- Use arrays of fixed size rather than pointers.
- Reduce the memory usage of sparse segment tree to while maintaining the same insertion time (see the solution for IOI Game below for details).
- Use BBSTs instead of sparse segment trees. memory, insertion time.
Problems
Can also try the USACO problems from above.
Status | Source | Problem Name | Difficulty | Tags | Solution | URL |
---|---|---|---|---|---|---|
POI | Hard | Show Tags2D, Lazy SegTree | External Sol | |||
IOI | Hard | Show Tags2D, Sparse SegTree | External Sol | |||
JOI | Very Hard | Show Tags2D, SegTree | External Sol |
Module Progress:
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!