0

I have N points denoted by (xi,yi).

1<=i<=N

I have Q queries of the following form :

Given a rectangle (aligned with x,y axes) defined by the points x1, y1, x2, y2 where (x1, y1) is the lower left corner and (x2, y2) is the upper right corner, find the number of points inside the rectangle. Points on rectangle are considered outside.

Constraints :
1 ≤ N ≤ 100 000
1 ≤ Q ≤ 100 000
0 ≤ xi, yi ≤ 100 000
0 ≤ x1 < x2 ≤ 100 000
0 ≤ y1 < y2 ≤ 100 000

I have thought of following approaches :

  1. Build a 2D segment tree on N*N matrix. A query will be solved in log N time. But the size of the segment tree built would be >=10^7. Hence memory insufficient.

  2. Keep two arrays(say X and Y), with both array containing all the N points. X is sorted with respect to x coordinates and Y is sorted with respect to y coordinate. Now given x1,y1,x2,y2 : I can find all points >=x1 && <=x2 from X array in log N time. Similarly, I can find all points >=y1 && <=y2 from Y in log N time. But how to find number of points in given rectangle, I cannot workout out further!

Complexity should be O(NlogN) or O(QlogN)

halfer
  • 19,824
  • 17
  • 99
  • 186
habaddu arya
  • 119
  • 1
  • 1
  • 8
  • Surely that O(NlogN) is typo? It is worse than O(N), ie. simply testing each point individually... Or what does it mean with respect of Q if it isn't a typo? – hyde Sep 11 '16 at 09:15
  • Not a typo! Maybe some method, where we take Q points ,then do the computation. Overall complexity for Q queries turn out to be O(Nlog N). Like sqrt-decomposition something maybe! – habaddu arya Sep 11 '16 at 09:19
  • Ah, so you'd loop through points once and add to matching queries. But shouldn't Q still matter, since queries can be overlapping (I assume, can they?), so if all points match all queries, it would take NQ operations. – hyde Sep 11 '16 at 09:26
  • O(NQ) is easy.Obviously I have thought of such solution as I have already given better solution than that in my given approaches. Q would matter,I guess! – habaddu arya Sep 11 '16 at 09:29
  • 1
    Anyway, look up BSP trees for inspiration. You need to do something like that. – hyde Sep 11 '16 at 09:38
  • Just an idea : to lower N*Q you may divide your area in subareas, and then apply your algorithm to each subarea. Points are assigned to only one area and rectangle are assigned to all areas they intersect. The idea here, is to lower execution time by lowering the number of comparisons with the addition to new properties to points and rectangles. – SR_ Sep 11 '16 at 09:40
  • Are all x's and y's integers? – Lior Kogan Sep 11 '16 at 18:23
  • Yes..! @LiorKogan – habaddu arya Sep 12 '16 at 20:07
  • Google orthogonal range searching on a grid. Many optimizations were presented. – Lior Kogan Sep 13 '16 at 03:48

2 Answers2

3

This problem is called Orthogonal Range Searching:

Given a set of n points in Rd, preprocess them such that reporting or counting the k points inside a d-dimensional axis-parallel box will be most efficient.

Your queries are range counting queries (not range reporting queries).

A two-dimensional range tree can be used to answer a range counting query in O(log n) time using O(n log n) storage (see for example Ch.36 of Handbook of Discrete and Computational Geometry 2Ed, 2004)

If your x's and y's are on a grid, and the grid is narrow, see Orthogonal range searching in linear and almost-linear space [Nekrich, 2009] where an O((logn / log logn)2) time data structure is presented.

Lior Kogan
  • 19,919
  • 6
  • 53
  • 85
0

Create a map<x, y>, populate it with all coordinates, then sort with comparator (sort by key then by value):

 return a.first != b.first?  a.first < b.first : a.second < b.second;

So that you can have y value sorted as well with a particular x key.

Now you need to traverse within >=x1 && <=x2 incrementally, and apply binary search to find y_min and y_max by passing iterator_start_for_xi and iterator_end_for_xi as start and end index.

Count at xi = iterator_for_xi_y_max - iterator_for_xi_y_min.

You need to find summation of count at xi where x1<=xi<=x2

For example, a map upon sorting would look like this:

2 6
3 4
3 5 
3 10
3 12 
3 25
5 1 
5 5
5 15
6 6
6 20
8 0

Lets say the x1 = 3, x2 = 7, y1 = 3, y2 = 12

2 6
3 4   < y_min for x = 3
3 5   <
3 10  <
3 12  < y_max for x = 3
3 25
5 1 
5 5   < y_min and y_max for x = 5
5 15  
6 6   < y_min and y_max for x = 6
6 20
8 0
Saurav Sahu
  • 13,038
  • 6
  • 64
  • 79