We are given N (N <= 106) points on a 2D plane and an integer D (N <= 106), we want to find two points p1,p2 (p2 to the right of p1) such that the difference between p1.y
and p2.y
is at least D and p2.x - p1.x
is minimized.
The x and y axis are in the range 0..106
This is a problem from a USACO past contest.
Here is my attempt to solve it:
MAXY = The maximum y axis among the N points.
Suppose we know p1, then we can find p2 quite easily; by taking all the points which have their y-axis in the range p1.y+D
to MAXY or in the range 0 to p1.y-D
and take the point which has the smallest x-axis greater than p.x
. This will be the best choice for p2.
But as we don't know p1, we will have to try all points for p1 and so finding the best choice for p2 should be done efficiently.
I used a segment tree for that. Every node in the tree will store all the points in the corresponding range in sorted order of x-axis. While querying, if a node falls in the query range then we binary search on the array for p1.x
and return the smallest element greater than it.
For every choice of p1, we query the tree twice with the ranges 0,p1.y-D and p1.y+D,MAXY and take the best of the two points returned.
The building of the tree can be done in O(NlogN) time. Every query will take O(logN*logN) time, and we make N queries, so the total time taken is (Nlogn*logn) which might not run within the time limits of 2 seconds. (106*20*20). Also the memory taken will be O(NlogN) which is about 80 mb (100000*20*4 kb) which is too much as the limit is 64 mb.
How can we do the queries faster and using lesser space?