Range Queries with Sweep Line
Authors: Benjamin Qi, Andi Qu, Dong Liu, Peng Bai
Solving 2D grid problems using 1D range queries.
Focus Problem – try your best to solve this problem before continuing!
Solution - Intersection Points
We can sweep from bottom to top (by the coordinate); storing two events for vertical segments (one for start and one for end) and one event for horizontal segments.
We can use a Binary Indexed Tree to store the number of active vertical segments for each coordinate.
Then, every time we encounter the start of a vertical segment, we increment the counter for in the BIT.
Similarly, we decrement the counter for every time we see the end of a vertical segment.
When we encounter a horizontal segment, we would query the number of active ranges in where is the lower coordinate and is the upper coordinate of the segment.
Our answer would be the sum of all the queries.
Implementation
Time Complexity:
C++
#include <bits/stdc++.h>using namespace std;Code Snippet: BIT (from the PURS module) (Click to expand)const int MAX_POS = 1e6;int main() {int n;cin >> n;
Focus Problem – try your best to solve this problem before continuing!
Solution - Springboards
Naive DP:
The first step is to create a DP to solve the first subtask. The states are the springboards and the transitions are between springboards. First, sort the springboards by the pair in increasing order. It is possible to show that for all , , where , Bessie cannot use springboard then later.
For each springboard , let denote the minimum distance needed to walk to the start point of springboard .
Let be the walking distance from the end of springboard and the start of springboard .
Then, the transitions are:
Full Solution:
Optimizing the DP involves the use of a min point update range query segment tree. Let's first expand in the transition formula.
We notice that everything inside the statement only depends on . The segment tree stores at index . We can seperate the start and end of springboards to create two seperate events for each springboard, still sorting by . When the event is the start of a springboard, update through a segment tree query. When the event is the end of a springboard, update the segment tree.
By processing in order, the first two conditions in the statement are always satisfied. The third is where the segment tree comes into play, where querying the range is sufficent to satisfy all constraints.
Due to the large , coordinate compression is required in the code.
Implementation
Time Complexity:
C++
#include <bits/stdc++.h>using namespace std;Code Snippet: Segment Tree (from the PURS module) (Click to expand)struct Point {int x, y;int i;bool is_start;
Alternate Approach
It turns out there is also a simpler though less straightforward method to solve this problem.
The problem boils down to having a data structure that supports the following operations:
- Add a pair .
- For any , query the minimum value of over all pairs satisfying .
This solution is described in the official editorial and the other module.
Problems
Status | Source | Problem Name | Difficulty | Tags | |
---|---|---|---|---|---|
HE | Easy | Show TagsPURS | |||
Platinum | Normal | Show TagsPURQ | |||
Platinum | Normal | ||||
CSES | Hard | Show TagsPURQ | |||
IZhO | Hard | Show TagsLazy SegTree, PURQ, Stack |
LIS Problems
Status | Source | Problem Name | Difficulty | Tags | |
---|---|---|---|---|---|
Balkan OI | Hard | Show TagsDP, PURS | |||
COCI | Hard | Show TagsDP, PURS | |||
Platinum | Very Hard | Show TagsDP |
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!