Orthogonal Problems
aka 正交问题
input: set P of n points
goal: process P in a DS
query: axis-aligned rectangle r
orthogonal range counting: number of points in r
orthogonal range reporting: list of points in r
3-sided queries: 3 boundaries
Rectangle stabbing
aka 穿刺矩形
input: set P of n rectangles
goal: process P in a DS
query: a point q
output: list of rectangles containing q
1D Orthogonal Range Searching
input: set P of n points in 1D
goal: process P in a DS
query: axis-aligned rectangle r→ an interval
solution
balanced BST + linked list
O(n) space and O(logn) time to count, O(logn+k) time to report
query interval covered by logn canonical sets 规范集.
可以证明任意一个区间包含的规范集个数是 logn 数量级的。
canonical set: subset contained in the subtree of a node of the BST
规范集:BST 中特定节点的子树中包含的元素集。它包括节点子树中的所有元素。
更简单一点的解释就是,规范集是一颗完整的子树。
v highest node that splits the interval
cover the part of the interval to left and right of v with O(logn) canonical sets
left w child of v:
- outside interval: move right
- inside interval: move left, add right can. set to cover.
cover the part of the interval to left and right of v with O(logn) canonical sets
total size of the canonical sets: O(nlogn)
Range Trees
input: set P of n points in 2D
goal: process P in a data structure
query: axis-alligned rectangle r
building the DS:
- a BST T on P ordered by x-coordinates
- a BST T(S) for every canonical set S of T ordered by y-coordinates
树套树:二叉搜索树套二叉搜索树?
T(S) is called a secondary DS.
canonical sets of T(S) are called secondary canonical sets.
answering query r=[x1,x2]×[y1,y2]:
- cover [x1,x2] with l=O(logn) canonical sets S1,⋯,Sl from T
- for each Si, cover [y1,y2] with O(logn) secondary canonical sets.
query time: O(log2n) (n is number of secondary canonical sets)
space analysis: ∑S∣T(S)∣=∑SO(∣S∣)=O(nlogn)
Range Trees in Higher Dimensions
input: set P of n points
goal: process P in a DS
query: axis-aligned rectangle r
assume, we have a DS Ad with Sd(n) space and Qd(n) query time for d-dimensional rectangles
Sd(n)=O(nlogd−1n)Qd(n)=O(logdn)
RTd+1(P):
- partition P into 2 subsets P1,P2 of ⌊2n⌋ and ⌈2n⌉ using a hyperplane h perpendicular 垂直 to the d+1 dimension
- project P1 onto h and store the projected points in a DS Ad(P1)
- project P2 onto h and store the projected points in a DS Ad(P2)
- recurse on P1,P2
Sd+1(n)=O(2Sd(2n))+2Sd+1(2n)=O(Sd(n))+2Sd+1(2n)=O(lognSd(n))
Queryd+1(q):
- if q completely to one side of h then recurse on either P1 or P2
- else
- let q=q′×[l,r]
- QueryULd+1(q′×(−∞,r]) on P1
- QueryULd+1(q′×[l,+∞) on P2
降为:在二分时,能保证子树不会超过这个范围。
QueryULd+1(q):
- let q=q′×(−∞,r]
- if q completely to left of h then recurse on P2
- else
- QueryULd+1(q′×(−∞,r]) on P1
- Queryd(q′) on the projection of P2 on h
Qd+1(n)=O(2Qd+1UL(2n))=O(Qd+1UL(n))Qd+1UL(n)=Qd+1UL(2n)+Qd(n)⇒O(lognQd(n))
Priority Search Tree
input: set P of n points
goal: process P in a DS
query: 3-sided rectangle [x1,x2]×[y,∞)
output: list of points in the query
PST(P):
- p← point in P with highest y-coordinate
- Pl←⌊2n−1⌋ points of P−{p} with smallest x-coordinate
- Pr=P−(Pl∪{p})
- create a node v, sotre p at v.p, the x-coordinate of the dividing line at v.d.
- left child of v←PST(Pl)
- right child of v←PST(Pr)
- return v
O(n) space
3SQuery(v,q):
- if v.p below q then return
- if v.p inside q then output v.p
- if q is to the left of v.d then 3SQuery(v.l,q)
- else if q is to the right of v.d then 3SQuery(v.r,q)
- else
3SQuery(vl,q)
3SQuery(vr,q)
in fact, 3S there is 2S.
因为保证了子树的范围不会超
2SQuery(v,q):
- if v.p below q then return
- if v.p inside q then output v.p
- if q is to the left of v.d then 2SQuery(v.l,q)
- else if q is to the right of v.d then 2SQuery(v.r,q)
- else
- 2SQuery(vl,q)
- 2SQuery(vr,q)
in fact, a 2-sided query + a 1-sided query = 3-sided query
{T3(n)=O(1)+T3(2n)T3(n)=O(1)+2T2(2n){T2(n)=O(1)+T2(2n)T2(n)=O(1)+T2(2n)+T1(2n)T1(n)=O(output size)T2(n)=O(logn+k)T3(n)=O(logn+k)
O(n) space, O(logn+k) query time