--- id: 2DRQ title: "2D Range Queries" author: Benjamin Qi prerequisites: - Platinum - Range Update Range Query description: "Extending Range Queries to 2D (and beyond)." frequency: 1 --- export const metadata = { problems: { bitSam: [ new Problem("CSES", "Forest Queries II", "1739", "Easy", false, ["2D BIT"], "[thecodingwizard's implementation](https://github.com/thecodingwizard/competitive-programming/blob/master/cses/Forest%20Queries%20II.cpp)"), ], bit: [ new Problem("DMOJ", "Crowded Cities", "bfs17p6", "Normal", false, ["2D Max BIT"], ""), new Problem("IOI", "Pairs", "https://wcipeg.com/problem/ioi0722", "Normal", false, ["3D BIT"], ""), ], offSam: [ new Problem("DMOJ", "Soriya's Programming Project", "dmopc19c7p5", "Normal", false, ["2D BIT"], ""), ], off: [ new Problem("Plat", "Friendcross", "722", "Hard", false, ["2D BIT"], ""), new Problem("Plat", "Mowing the Field", "601", "Hard", false, ["2D BIT"], ""), ], seg: [ new Problem("POI", "Tetris 3D", "https://szkopul.edu.pl/problemset/problem/OQjANSOOD_-c38gh8p6g3Gxp/site/?key=statement", "Hard", false, ["2D Seg"], ""), new Problem("ojuz", "IOI 2013 - Game", "IOI13_game", "Very Hard", false, ["2D Seg"], "Alternatively, use BBST in place of sparse segment tree (see Advanced - Treaps)"), new Problem("ojuz", "JOI - Golf", "JOI17_golf", "Very Hard", false, ["Seg"], ""), ], } }; See [my implementations](https://github.com/bqi343/USACO/tree/master/Implementations/content/data-structures/2D%20Range%20Queries%20(15.2)). ## 2D RMQ - GP of Serbia 2020 B ## 2D BIT ### Tutorial ### Problems 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](https://arxiv.org/pdf/1311.6093.pdf) for details. - USACO Camp - "Cows Play Global Thermonuclear War" (2D case) ## 2D Offline Sum Queries The intended complexity is $O(N\log^2 N)$ with a good constant factor. This requires updating points and querying rectangle sums $N$ times for points with coordinates in the range $[1,N]$. However The 2D BITs mentioned above use $O(N^2)$ memory, which is too much. 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 $O(N\log^2N)$ memory and time and the constant factors for both are terrible. ### Idea 2: Compress the points to be updated so that you only need $O(N\log N)$ memory. This doesn't require knowing the queries beforehand. - [my 1D offline BIT](https://github.com/bqi343/USACO/blob/master/Implementations/content/data-structures/1D%20Range%20Queries%20(9.2)/BIToff.h) - [my 2D offline BIT](https://github.com/bqi343/USACO/blob/master/Implementations/content/data-structures/2D%20Range%20Queries%20(15.2)/BIT2DOff%20(15.2).h) It's a bit difficult to pass the above problem within the time limit. Make sure to use fast input (and not `endl`)! - [thecodingwizard's implementation with 2D offline BIT above](https://github.com/thecodingwizard/competitive-programming/blob/master/DMOJ/Soriyas%20Programming%20Project.cpp) ### Idea 3: Use divide & conquer with a 1D BIT - mentioned in [this article](https://robert1003.github.io/2020/01/31/cdq-divide-and-conquer.html) - [thecodingwizard's (messy) implementation](https://github.com/thecodingwizard/competitive-programming/blob/master/DMOJ/Soriya%20Programming%20Project%201d%20BIT%20cdq%20dnc.cpp) based off above ### Problems ## 2D Segment Tree Basically a segment tree of (maybe sparse) segment trees (or BBSTs, see "Advanced - Treap"). This is **not** the same as [Quadtree](https://en.wikipedia.org/wiki/Quadtree). If the coordinates go up to $C$, then 2D segment tree queries run in $O(\log^2C)$ time each but some queries make Quadtree take $\Theta(C)$ time! ### Short Description brief description code ### Reducing Memory Usage Naively, inserting $N$ elements into a sparse segment tree requires $O(N\log C)$, giving a memory bound of $O(N\log^2C)$ on 2D segment tree memory. This is usually too much for $N=10^5$ (although it sufficed for "Mowing the Field" due to the higher memory limit). To resolve this, reduce the memory usage of sparse segment tree while maintaing the same $O(N\log C)$ insertion time (see the solution for IOI Game below for details). (implementation) ### Problems Can also try the USACO problems from above.