我有(xi,yi)表示的N个点。
1·; = I< = N
我有以下表格的Q查询:
给定由点x1,y1,x2,y2定义的矩形(与x,y轴对齐),其中(x1,y1)是左下角,(x2,y2)是右上角,找到矩形内的点数。矩形上的点被视为外部。
Constraints :
1 ≤ N ≤ 100 000
1 ≤ Q ≤ 100 000
0 ≤ xi, yi ≤ 100 000
0 ≤ x1 < x2 ≤ 100 000
0 ≤ y1 < y2 ≤ 100 000
我想到了以下方法:
在N * N矩阵上构建2D分段树。查询将在log N时间内解决。 但是构建的分段树的大小将是> = 10 ^ 7。因此记忆力不足。
保留两个数组(比如X和Y),两个数组都包含所有N个点。 X相对于x坐标排序,Y相对于y坐标排序。现在给出x1,y1,x2,y2:我可以找到所有点&gt; = x1&amp;&amp;在log N时间内从X数组&lt; = x2。同样,我可以找到所有点&gt; = y1&amp;&amp;在log N时间中从Y开始&lt; = y2。但是如何在给定的矩形中找到点数,我无法进一步锻炼!
复杂性应为O(NlogN)或O(QlogN)
答案 0 :(得分:2)
此问题称为正交范围搜索:
给定R d 中的一组n个点,预处理它们以便报告或 计算d维轴平行框内的k点将是 效率最高。
您的查询是范围计数查询(不是范围报告查询)。
使用O(n log n)存储,可以使用二维范围树在O(log n)时间内回答范围计数查询(参见例如Ch.36 of Handbook of Discrete and Computational Geometry 2Ed, 2004)
如果您的x和y在网格上,并且网格很窄,请参阅Orthogonal range searching in linear and almost-linear space [Nekrich, 2009]其中的O((logn / log logn) 2 )提供时间数据结构。
答案 1 :(得分:1)
创建一个map<x, y>
,用所有坐标填充它,然后用比较器排序(按键排序,然后按值排序):
return a.first != b.first? a.first < b.first : a.second < b.second;
这样您就可以使用特定的y
密钥对x
值进行排序。
现在,您需要逐步遍历>=x1 && <=x2
,并应用 二进制搜索 ,通过{y_min
和y_max
{1}}和iterator_start_for_xi
为iterator_end_for_xi
和start
索引。
依靠end
= xi
- iterator_for_xi_y_max
计算。
您需要在iterator_for_xi_y_min
xi
例如,排序时x1<=xi<=x2
如下所示:
map
让我们说2 6
3 4
3 5
3 10
3 12
3 25
5 1
5 5
5 15
6 6
6 20
8 0
x1 = 3, x2 = 7, y1 = 3, y2 = 12