We are given N (N <= 10 6 ) points on the 2D plane and an integer D (N <= 10 6 ), we want to find two points p1, p2 (p2 to the right of p1), so the difference between p1.y
and p2.y
not less than D and p2.x - p1.x
minimized.
The x and y axis is in the range of 0.10 6
This is a problem from the past USACO contest.
Here is my attempt to solve it:
MAXY = maximum y axis among N points.
Suppose we know p1, then we can easily find p2; taking all points whose y axis is in the range p1.y+D
, MAXY, or in the range from 0 to p1.yD
, and take the point that has the smallest x axis greater than px
. This will be the best choice for p2.
But, since we do not know p1, we will have to try all the points for p1, and therefore the search for the best choice for p2 should be carried out efficiently.
I used a segment tree for this. Each node in the tree will store all the points in the corresponding range in sorted order along the x axis. When querying, if node falls into the query range, we get a binary search in the array for p1.x
and return the smallest element larger than it.
For each p1 selection, we query the tree twice with ranges 0, p1.yD and p1.y + D, MAXY and take the best of the two returned points.
Tree building can be done in O (NlogN) time. Each request will take O (logN * logN) time, and we make N requests, so the total time (Nlogn * logn), which may not be executed for 2 seconds. (10 6 * 20 * 20). Also, O (NlogN) memory will be made, which is about 80 mb (100000 * 20 * 4 kb), which is too large, since the limit is 64 mb.
How to make queries faster and use less space?