\documentclass[11pt]{article}
\usepackage{latexsym}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsthm}
\usepackage{epsfig}
\usepackage{psfig,pstricks}

\newcommand{\handout}[5]{
  \noindent
  \begin{center}
  \framebox{
    \vbox{
      \hbox to 5.78in { {\bf 6.851: Advanced Data Structures } \hfill #2 }
      \vspace{4mm}
      \hbox to 5.78in { {\Large \hfill #5  \hfill} }
      \vspace{2mm}
      \hbox to 5.78in { {\em #3 \hfill #4} }
    }
  }
  \end{center}
  \vspace*{4mm}
}

\newcommand{\lecture}[4]{\handout{#1}{#2}{#3}{Scribe: #4}{Lecture #1}}

\newtheorem{theorem}{Theorem}
\newtheorem{corollary}[theorem]{Corollary}
\newtheorem{lemma}[theorem]{Lemma}
\newtheorem{observation}[theorem]{Observation}
\newtheorem{proposition}[theorem]{Proposition}
\newtheorem{definition}[theorem]{Definition}
\newtheorem{claim}[theorem]{Claim}
\newtheorem{fact}[theorem]{Fact}
\newtheorem{assumption}[theorem]{Assumption}

% 1-inch margins, from fullpage.sty by H.Partl, Version 2, Dec. 15, 1988.
\topmargin 0pt
\advance \topmargin by -\headheight
\advance \topmargin by -\headsep
\textheight 8.9in
\oddsidemargin 0pt
\evensidemargin \oddsidemargin
\marginparwidth 0.5in
\textwidth 6.5in

\parindent 0in
\parskip 1.5ex
%\renewcommand{\baselinestretch}{1.25}


\newenvironment{bulletItemize}
{\renewcommand{\labelitemi}{$\bullet$}\begin{itemize}}
{\end{itemize}\renewcommand{\labelitemi}{--}}

%
%
%


\newcommand{\RR}{\mathbb R}


\renewcommand{\labelitemi}{--}

\begin{document}

\lecture{4 --- February 11, 2010}{Spring 2010}{Prof.\ Andr\'e Schulz}{Peter Caday}

\section{Overview}

In the previous lecture, we studied range trees and kd-trees, two structures which support efficient orthogonal range queries on a set of points. In this second of four lectures on geometric data structures, we will tie up a loose end from the last lecture --- handling insertions and deletions. The main topic, however, will be two new structures addressing the \emph{vertical line stabbing} problem: interval trees and segment trees. We will conclude with an application of vertical line stabbing to a windowing problem.

\section{Dynamization}

In our previous discussion of range trees, we assumed that the point set was static. On the other hand, we may be interested in supporting insertions and deletions as time progresses. Unfortunately, it is not trivial to modify our data structures to handle this dynamic scenario. We can, however, dynamize them using general techniques; the techniques and their application here are due to Overmars~\cite{overmars}. 

\paragraph{Idea.} Overmars' dynamization is based on the idea of \emph{decomposable searches}. A search $(X,q)$ for the value $q$ among the keys $X$ is decomposable if the search result can be obtained in $O(1)$ time from the results of searching $(X_1,q)$ and $(X_2,q)$, where $X_1\cup X_2=X$. For instance, in the 2D kd-tree, the root node splits $\RR^2$ into two halves. If we want to search for all points lying in a rectangle $q$, we may do this by combining the results of searching for $q$ in each half.

\paragraph{Results.} We will bypass the actual dynamization method, and just give the results. 

\begin{itemize}
\item \emph{Insertion:} $O((\log n)^{T_b/n})$, where $T_b$ is the \emph{build time}, the time required to build the static tree
\item \emph{Query:} time increases by a $\log n$ factor
\end{itemize}

Note that this is a general result, which applies to any data structure with a decomposable search.
As a concrete example, here are the times for a dynamic 2D range tree:

\begin{itemize}
\item \emph{Insertion:} $O(\log^2 n+k)$, where $k$ is the size of the output, as always
\item \emph{Query:} $O(\log^2 n)$
\end{itemize}

We have only mentioned insertion time here; deletions are more complicated. 

\section{Vertical line stabbing}

We now move to the main focus of this lecture. In the \emph{vertical line stabbing} problem, the input is a collection $I=\{[a_1,b_1],[a_2,b_2],\dotsc\}$ of $n$ closed intervals. We wish to be efficiently report, for any $q\in\RR$, the intervals containing $q$.
The name ``vertical line stabbing'' derives from one way to visualize the problem:

\[
\ifx\JPicScale\undefined\def\JPicScale{1}\fi
\psset{unit=\JPicScale mm}
\psset{linewidth=0.3,dotsep=1,hatchwidth=0.3,hatchsep=1.5,shadowsize=1,dimen=middle}
\psset{dotsize=0.7 2.5,dotscale=1 1,fillcolor=black}
\psset{arrowsize=1 2,arrowlength=1,arrowinset=0.25,tbarsize=0.7 5,bracketlength=0.15,rbracketlength=0.15}
\begin{pspicture}(0,0)(57.5,35)
\psline[linewidth=0.15](2.5,2.12)(57.5,2.12)
\psline[linewidth=0.15](57.5,2.12)(56.52,1.06)
\psline[linewidth=0.15](56.52,3.18)(57.5,2.12)
\psline[linewidth=0.4](30,0)(30,35)
\psline[linewidth=0.15](22.14,25.45)(31.96,25.45)
\psline[linewidth=0.15](31.96,26.52)(31.96,24.39)
\psline[linewidth=0.15](22.14,26.52)(22.14,24.39)
\psline[linewidth=0.15](8.39,20.15)(8.39,18.03)
\psline[linewidth=0.15](8.39,19.09)(20.18,19.09)
\psline[linewidth=0.15](20.18,20.15)(20.18,18.03)
\psline[linewidth=0.15](28.04,20.15)(28.04,18.03)
\psline[linewidth=0.15](28.04,19.09)(51.61,19.09)
\psline[linewidth=0.15](51.61,20.15)(51.61,18.03)
\psline[linewidth=0.15](16.25,13.79)(16.25,11.67)
\psline[linewidth=0.15](16.25,12.73)(39.82,12.73)
\psline[linewidth=0.15](39.82,13.79)(39.82,11.67)
\psline[linewidth=0.6](29.51,25.98)(30.49,24.92)
\psline[linewidth=0.6](30.49,25.98)(29.51,24.92)
\psline[linewidth=0.6](29.51,19.62)(30.49,18.56)
\psline[linewidth=0.6](30.49,19.62)(29.51,18.56)
\psline[linewidth=0.6](29.51,13.26)(30.49,12.2)
\psline[linewidth=0.6](30.49,13.26)(29.51,12.2)
\rput{90}(30,2.12){\psellipse[linestyle=none,fillstyle=solid](0,0)(0.53,-0.49)}
\rput(33.04,4.09){q}
\end{pspicture}
\]

\subsection{Interval Tree}

\paragraph{Idea.} One way to address the problem is through a divide-and-conquer approach. Consider the median $m$ of the $2n$ endpoints in $I$. Some intervals may lie entirely to the left of $m$, some entirely to the right, and some may cross $m$. Thos to the left and to the right can be dealt with recursively. On the other hand, the intervals crossing $m$ seem problematic. Suppose we have a query $q<m$. We may sort the intervals crossing $m$ by their left endpoints:

\[
\ifx\JPicScale\undefined\def\JPicScale{1}\fi
\psset{unit=\JPicScale mm}
\psset{linewidth=0.3,dotsep=1,hatchwidth=0.3,hatchsep=1.5,shadowsize=1,dimen=middle}
\psset{dotsize=0.7 2.5,dotscale=1 1,fillcolor=black}
\psset{arrowsize=1 2,arrowlength=1,arrowinset=0.25,tbarsize=0.7 5,bracketlength=0.15,rbracketlength=0.15}
\begin{pspicture}(0,0)(108.57,35)
\psline[linewidth=0.4](28.75,0)(28.75,35)
\psline[linewidth=0.15](25,8.75)(34.82,8.75)
\psline[linewidth=0.15](34.82,9.81)(34.82,7.69)
\psline[linewidth=0.15](25,9.81)(25,7.69)
\psline[linewidth=0.15](27.5,25)(27.5,22.88)
\psline[linewidth=0.15](27.5,23.94)(39.29,23.94)
\psline[linewidth=0.15](39.29,25)(39.29,22.88)
\psline[linewidth=0.15](16.43,31.06)(16.43,28.94)
\psline[linewidth=0.15](16.43,30)(40,30)
\psline[linewidth=0.15](40,31.06)(40,28.94)
\psline[linewidth=0.15](21.25,17.31)(21.25,15.19)
\psline[linewidth=0.15](21.25,16.25)(44.82,16.25)
\psline[linewidth=0.15](44.82,17.31)(44.82,15.19)
\rput(23.75,1.25){q}
\psline[linestyle=dotted](23.75,3.75)(23.75,33.75)
\psline[arrowscale=2 1.5]{->}(52.5,18.75)(71.25,18.75)
\rput(61.25,22.5){sort}
\psline[linewidth=0.4](92.32,0)(92.32,35)
\psline[linewidth=0.15](88.75,16.25)(98.57,16.25)
\psline[linewidth=0.15](98.57,17.31)(98.57,15.19)
\psline[linewidth=0.15](88.75,17.31)(88.75,15.19)
\psline[linewidth=0.15](91.25,9.81)(91.25,7.69)
\psline[linewidth=0.15](91.25,8.75)(103.04,8.75)
\psline[linewidth=0.15](103.04,9.81)(103.04,7.69)
\psline[linewidth=0.15](80,31.06)(80,28.94)
\psline[linewidth=0.15](80,30)(103.57,30)
\psline[linewidth=0.15](103.57,31.06)(103.57,28.94)
\psline[linewidth=0.15](85,24.81)(85,22.69)
\psline[linewidth=0.15](85,23.75)(108.57,23.75)
\psline[linewidth=0.15](108.57,24.81)(108.57,22.69)
\rput(87.32,1.25){q}
\psline[linestyle=dotted](87.32,3.75)(87.32,33.75)
\end{pspicture}
\]

With this sorting, the intervals containing $q$ can be listed easily, starting from the leftmost interval and stopping when we reach an interval lying to the right of $q$. All the intervals we examine, except for the last, contain $q$, so the searching process requires time linear in the output size. If $q$ were on the right of $m$, instead, we would sort the intervals by their right endpoints.

\paragraph{Example.} Take $I=\{[1,6],[3,20],[3,7],[5,17],[10,20],[13,15]\}$. Taking 10 as the median of the endpoints, we have three classes of intervals:
\begin{align*}
I_l&=\{[1,6],[3,7]\}	&& \text{(intervals left of median)}\\
I_m&=\{[3,20],[5,17],[10,20]\}		&& \text{(intervals crossing median)}\\
I_r&=\{[13,15]\}		&& \text{(intervals right of median)}
\end{align*}

We now construct a binary tree for $I$, which will be its interval tree. We recursively store the interval trees for $I_l$ and $I_r$ in the left and right children of the root node. Then, we put two copies of $I_m$ in the root node itself, one copy sorted by left endpoint, one by right endpoint:

\[
\ifx\JPicScale\undefined\def\JPicScale{1}\fi
\psset{unit=\JPicScale mm}
\psset{linewidth=0.3,dotsep=1,hatchwidth=0.3,hatchsep=1.5,shadowsize=1,dimen=middle}
\psset{dotsize=0.7 2.5,dotscale=1 1,fillcolor=black}
\psset{arrowsize=1 2,arrowlength=1,arrowinset=0.25,tbarsize=0.7 5,bracketlength=0.15,rbracketlength=0.15}
\begin{pspicture}(0,0)(105,40)
\rput{0}(65.56,8.89){\psellipticarc[linewidth=0.25](0,0)(21.21,21.21){16.73}{84.22}}
\pspolygon[linewidth=0.15,fillcolor=white,fillstyle=solid](75,15)(105,15)(105,5)(75,5)
\rput{0}(39.44,8.39){\psellipticarc[linewidth=0.25](0,0)(21.21,21.21){95.78}{163.27}}
\pspolygon[linewidth=0.15,fillcolor=white,fillstyle=solid](0,15)
(30,15)
(30,0)
(0,0)(0,15)
\rput(60,35){[10,20]}
\rput(60,30){[3,20]}
\rput(60,25){[5,17]}
\rput(45,35){[3,20]}
\rput(45,30){[5,17]}
\rput(45,25){[10,20]}
\psline[linewidth=0.15](52.5,40)(52.5,20)
\pspolygon[linewidth=0.15](37.5,40)(67.5,40)(67.5,20)(37.5,20)
\rput(97.5,10){[13,15]}
\rput(82.5,10){[13,15]}
\psline[linewidth=0.15](90,15)(90,5)
\rput(7.5,5){[3,7]}
\rput(7.5,10){[1,6]}
\psline[linewidth=0.15](15,15)(15,0)
\rput(22.5,10){[3,7]}
\rput(22.5,5){[1,6]}
\rput(85,25){$I_r$}
\rput(20,25){$I_l$}
\end{pspicture}
\]

To search for 18, say, we first compare it to the median 10. We can ignore $I_l$, since $18>10$. Next, we search through $I_m$, finding the intervals $[3,20]$ and $[10,20]$. Finally, we recursively search for 18 in $I_r$, where there are no matching intervals.

\paragraph{Summary.} The interval tree has the following characteristics:

\begin{itemize}
\item \emph{Preprocessing:} $O(n\log n)$. Sorting $I_m$ requires $O(n\log n)$ time, and the median of $2n$ endpoints can be found in $O(n)$ time.
\item \emph{Storage:} $O(n)$. The tree structure takes up $O(n)$ space; each interval appears in only one node, and appears exactly twice there, for $O(n)$ total space.
\item \emph{Query:} $O(\log n+k)$. Searching through the intervals of each node requires time linear in the output size, contributing $O(k)$.
The height of the tree is $O(\log n)$ due to the use of the median. 
\end{itemize}

We have seen how to construct and query an interval tree:
\begin{itemize}
\item \emph{Construction:}
\begin{enumerate}
\item Split intervals among $I_l$, $I_m$, $I_r$.
\item Handle $I_m$ with two sorted lists.
\item Recursively construct $I_l$, $I_r$.
\end{enumerate}
\item \emph{Searching:}
\begin{enumerate}
\item Perform a binary search for $q$.
\item Scan the $I_m$ lists for stabbed intervals.
\end{enumerate}
\end{itemize}

\subsection{Segment Tree}

\paragraph{Construction.} The second data structure we will consider for vertical line stabbing is the \emph{segment tree}. We start by defining the construction of a segment tree, with the same $I$ used earlier as an example. The steps are as follows:

\begin{bulletItemize}
\item First, we split the real line into \emph{elementary intervals}. If $\{c_1,\dotsc,c_k\}$ is the set of endpoints in $I$ in increasing order, the elementary intervals are the single points $[c_i,c_i]$ together with the open intervals between them: $(c_i,c_{i+1})$.

\item We build a BST over the elementary intervals. Note that each node in the BST can be associated with the union of the elementary intervals belonging to the leaf nodes below it.
\[
\ifx\JPicScale\undefined\def\JPicScale{1}\fi
\psset{unit=\JPicScale mm}
\psset{linewidth=0.3,dotsep=1,hatchwidth=0.3,hatchsep=1.5,shadowsize=1,dimen=middle}
\psset{dotsize=0.7 2.5,dotscale=1 1,fillcolor=black}
\psset{arrowsize=1 2,arrowlength=1,arrowinset=0.25,tbarsize=0.7 5,bracketlength=0.15,rbracketlength=0.15}
\begin{pspicture}(0,0)(108,34)
\psline[linewidth=0.15](42,31)(71,33)
\psline[linewidth=0.15](71,33)(92,25)
\psline[linewidth=0.15](22,28)(42,31)
\psline[linewidth=0.15](62,28)(42,31)
\psline[linewidth=0.15,arrowscale=1.5 1.5]{->}(5,15)(108,15)
\psline[linewidth=0.15](10,17)(10,13)
\psline[linewidth=0.15](20,17)(20,13)
\psline[linewidth=0.15](30,17)(30,13)
\psline[linewidth=0.15](40,17)(40,13)
\psline[linewidth=0.15](50,13)(50,17)
\psline[linewidth=0.15](60,17)(60,13)
\psline[linewidth=0.15](70,17)(70,13)
\psline[linewidth=0.15](80,13)(80,17)
\psline[linewidth=0.15](90,17)(90,13)
\psline[linewidth=0.15](100,17)(100,13)
\rput(10,9){1}
\rput(20,9){3}
\rput(30,9){5}
\rput(40,9){6}
\rput(50,9){7}
\rput(60,9){10}
\rput(70,9){13}
\rput(80,9){15}
\rput(90,9){17}
\rput(100,9){20}
\rput{0}(71,33){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\psline[linewidth=0.15](12,25)(22,28)
\psline[linewidth=0.15](22,28)(32,25)
\psline[linewidth=0.15](7,22)(12,25)
\psline[linewidth=0.15](17,22)(12,25)
\psline[linewidth=0.15](10,19)(7,22)
\psline[linewidth=0.15](5,17)(7,22)
\rput{0}(10,19){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(5,17){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(7,22){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\psline[linewidth=0.15](20,19)(17,22)
\psline[linewidth=0.15](15,17)(17,22)
\rput{0}(20,19){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(15,17){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(17,22){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(12,25){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\psline[linewidth=0.15](27,22)(32,25)
\psline[linewidth=0.15](37,22)(32,25)
\psline[linewidth=0.15](30,19)(27,22)
\psline[linewidth=0.15](25,17)(27,22)
\rput{0}(30,19){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(25,17){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(27,22){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\psline[linewidth=0.15](40,19)(37,22)
\psline[linewidth=0.15](35,17)(37,22)
\rput{0}(40,19){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(35,17){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(37,22){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(32,25){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(22,28){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(42,31){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\psline[linewidth=0.15](52,25)(62,28)
\psline[linewidth=0.15](62,28)(72,25)
\psline[linewidth=0.15](47,22)(52,25)
\psline[linewidth=0.15](57,22)(52,25)
\psline[linewidth=0.15](50,19)(47,22)
\psline[linewidth=0.15](45,17)(47,22)
\rput{0}(50,19){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(45,17){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(47,22){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\psline[linewidth=0.15](60,19)(57,22)
\psline[linewidth=0.15](55,17)(57,22)
\rput{0}(60,19){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(55,17){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(57,22){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(52,25){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\psline[linewidth=0.15](67,22)(72,25)
\psline[linewidth=0.15](77,22)(72,25)
\psline[linewidth=0.15](70,19)(67,22)
\psline[linewidth=0.15](65,17)(67,22)
\rput{0}(70,19){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(65,17){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(67,22){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\psline[linewidth=0.15](80,19)(77,22)
\psline[linewidth=0.15](75,17)(77,22)
\rput{0}(80,19){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(75,17){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(77,22){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(72,25){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(62,28){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\psline[linewidth=0.15](87,22)(92,25)
\psline[linewidth=0.15](97,22)(92,25)
\psline[linewidth=0.15](90,19)(87,22)
\psline[linewidth=0.15](85,17)(87,22)
\rput{0}(90,19){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(85,17){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(87,22){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\psline[linewidth=0.15](100,19)(97,22)
\psline[linewidth=0.15](95,17)(97,22)
\rput{0}(100,19){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(95,17){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(97,22){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\rput{0}(92,25){\psellipse[linewidth=0.15,fillcolor=white,fillstyle=solid](0,0)(1,-1)}
\psbezier[linewidth=0.15]{<-}(32,17)(36,13)(37,10)(38,4)
\rput(38,2){[5,5]}
\psbezier[linewidth=0.15]{<-}(53,16)(50,13)(56,9)(56,4)
\rput(56,2){(7,10)}
\end{pspicture}
\]
\item As a first try, we store in each leaf node (elementary interval) the set of intervals in $I$ containing that node's interval. For instance, at the node for the $(3,5)$, we store $\{[1,6],[3,7],[3,20]\}$. The query time is good: $O(\log n)$ for searching and $O(k)$ for reporting. However, the storage required could be quadratic.

\item To improve the storage costs, we look to see if any two siblings store the same interval $[a_i,b_i]$. If so, we remove it from them and store it in their parent instead, and repeat until no two siblings store the same intervals.

\item After this process, the set of nodes storing any interval will subdivide that interval. In our example, $[3,7]$ will be stored in the nodes $[3]$, $(3,5]$, and $(5,7]$. This provides a canonical subdivision for each interval in $I$.
\end{bulletItemize}

\paragraph{Querying.} To query this tree for $q$, we simply perform a binary search for $q$ and report all intervals stored in the nodes we visit. This is quite different from the interval tree, where it was necessary to search through a list of potentially stabbed intervals. Here, every interval encountered is reported. The time required is $O(\log n+k)$, just as with interval trees.

\paragraph{Storage.} We claim that every level of the tree stores any interval at most twice. The proof is by contradiction. Suppose that some interval $J$ is stored in at least three vertices $v_1,\dotsc,v_k$ in some level, as depicted below.

\[
\ifx\JPicScale\undefined\def\JPicScale{1}\fi
\psset{unit=\JPicScale mm}
\psset{linewidth=0.3,dotsep=1,hatchwidth=0.3,hatchsep=1.5,shadowsize=1,dimen=middle}
\psset{dotsize=0.7 2.5,dotscale=1 1,fillcolor=black}
\psset{arrowsize=1 2,arrowlength=1,arrowinset=0.25,tbarsize=0.7 5,bracketlength=0.15,rbracketlength=0.15}
\begin{pspicture}(0,0)(40,50)
\psline[linewidth=0.15](-0,10)(20,50)
\psline[linewidth=0.15](40,10)(20,50)
\psline[linewidth=0.15](40,10)(-0,10)
\psline[linewidth=0.15,linestyle=dashed,dash=1 1](5,30)(35,30)
\pspolygon[linewidth=0.15,fillstyle=vlines](17.5,10)
(20,30)
(22.5,10)(17.5,10)
\pspolygon[linewidth=0.15,fillstyle=vlines](22.5,10)
(25,30)
(27.5,10)(22.5,10)
\pspolygon[linewidth=0.15,fillstyle=vlines](12.5,10)
(15,30)
(17.5,10)(12.5,10)
\rput{0}(15,30){\psellipse[linewidth=0.15,fillstyle=solid](0,0)(0.5,0.5)}
\rput{0}(20,30){\psellipse[linewidth=0.15,fillstyle=solid](0,0)(0.5,0.5)}
\rput{0}(25,30){\psellipse[linewidth=0.15,fillstyle=solid](0,0)(0.5,0.5)}
\rput(15,32.5){$v_1$}
\rput(20,32.5){$v_2$}
\rput(25,32.5){$v_3$}
\psline[linewidth=0.15,fillstyle=solid](12.5,7.5)(27.5,7.5)
\psline[linewidth=0.15,fillstyle=solid](27.5,8.75)(27.5,6.25)
\psline[linewidth=0.15,fillstyle=solid](12.5,8.75)(12.5,6.25)
\rput(20,5){$J$}
\end{pspicture}
\]

There cannot be any gaps between the subtrees rooted at each of these vertices, since $J$ covers all of the real line between them. Therefore, some pair $v_i$,$v_{i+1}$ must be siblings, a contradiction.

This claim shows that the segment tree requires $O(n\log n)$ storage. Although this seems worse than the interval tree, the segment tree has advantages for certain applications, as one of the homework problems shows.

\paragraph{Preprocessing.} First, we build the BST, which takes $O(n)$ time. We can streamline the process of storing the intervals in the tree by inserting them one at a time. As an example, to insert the interval $[3,7]$, we search for 3 and 7. At some node $v_{\text{split}}$, the search paths for 3 and 7 diverge. Continuing from $v_{\text{split}}$ to $[3,3]$, we can easily decide at each node whether $[3,7]$ should be stored (we will not worry about the details here). Similarly for the path from $v_{\text{split}}$ to $[7,7]$.

Altogether, storing the intervals requires $O(n\log n)$ time.

\section{Application: windowing}

Suppose we have a geometric data set containing a huge number of line segments, and want only the portion of this data lying within some window. For instance, we may have a state road map and need to a small portion of it for viewing in a GPS.
%
% picture?
%
We need to report all line segments that intersect $W$. There are two parts to this: finding everything with 1 or 2 endpoints inside $W$ (part A), and finding everything that intersects the border of $W$ twice (part B).

\paragraph{Part A.} This is really a range query, so we can use a 2D orthogonal range tree on the endpoints. We need to take care if a line segment has 2 endpoints in $W$, to avoid reporting line segments twice. %To solve this, we check every endpoint found in $W$ to see if the other endpoint on its line segment is also in $W$. If so, we only report the leftmost one, say.

\paragraph{Part B.} For simplicity, we consider the case of orthogonal line segments (every segment is either horizontal or vertical). The next figure illustrates that we can check for horizontal lines crossing $W$ using vertical line stabbing:

\[
\ifx\JPicScale\undefined\def\JPicScale{1}\fi
\psset{unit=\JPicScale mm}
\psset{linewidth=0.3,dotsep=1,hatchwidth=0.3,hatchsep=1.5,shadowsize=1,dimen=middle}
\psset{dotsize=0.7 2.5,dotscale=1 1,fillcolor=black}
\psset{arrowsize=1 2,arrowlength=1,arrowinset=0.25,tbarsize=0.7 5,bracketlength=0.15,rbracketlength=0.15}
\begin{pspicture}(0,0)(63.75,47.5)
\pspolygon[linewidth=0.4,fillstyle=vlines,hatchwidth=0.1](31.25,40)(56.25,40)(56.25,20)(31.25,20)
\psline[linewidth=0.15,fillstyle=solid,arrowscale=1.5 1.5]{->}(2.5,2.5)(2.5,47.5)
\psline[linewidth=0.15,fillstyle=solid]{*-*}(52.5,31.25)(63.75,31.25)
\psline[linewidth=0.15,fillstyle=solid]{*-*}(21.25,11.25)(60,11.25)
\psline[linewidth=0.15,fillstyle=solid]{*-*}(22.5,23.75)(38.75,23.75)
\psline[linewidth=0.15,fillstyle=solid]{*-*}(20,33.75)(58.75,33.75)
\psline[linewidth=0.15,fillstyle=solid]{*-*}(26.25,43.75)(47.5,43.75)
\psline[linewidth=0.15,fillstyle=solid]{*-*}(30,5)(42.5,5)
\end{pspicture}
\]

However, we need to get rid of the intervals lying above or below $W$. We will consider two approaches to doing so.

\begin{enumerate}
\item We form an interval tree for the horizontal lines, but store a 2D range tree with their $y$-values instead of the pair of sorted lists. Queries only require $O(\log^2 n+k)$ time, but the storage requirements are bad. 
\item We use a priority search tree, described next.
\end{enumerate}



\subsection{Priority search trees}

A priority search tree is a mixture of a BST and a heap. Like 2D range trees, these trees represent a 2D point set $\{p_1,p_2,\dotsc\}$. Unlike 2D range trees, the queries for a priority search tree are rectangles with one open side: $(-\infty,x_{\text{max}}]\times[y_{\text{min}},y_{\text{max}}]$.

\paragraph{Construction.} We store a point with least $x$-coordinate in the root of the tree, and let $y_m$ be the median of the remaining $y$-coordinates. In the left subtree, we store points with $y<y_m$ in a priority search tree, and in the right subtree, the points with $y\geq y_m$. The next picture provides an example of this construction.
\[
\ifx\JPicScale\undefined\def\JPicScale{1}\fi
\psset{unit=\JPicScale mm}
\psset{linewidth=0.3,dotsep=1,hatchwidth=0.3,hatchsep=1.5,shadowsize=1,dimen=middle}
\psset{dotsize=0.7 2.5,dotscale=1 1,fillcolor=black}
\psset{arrowsize=1 2,arrowlength=1,arrowinset=0.25,tbarsize=0.7 5,bracketlength=0.15,rbracketlength=0.15}
\begin{pspicture}(0,0)(150,45)
\rput{0}(17.5,22.5){\psellipse[linewidth=0.15,fillstyle=solid](0,0)(0.5,0.5)}
\rput{0}(2.5,27.5){\psellipse[linewidth=0.15,fillstyle=solid](0,0)(0.5,0.5)}
\rput{0}(27.5,7.5){\psellipse[linewidth=0.15,fillstyle=solid](0,0)(0.5,0.5)}
\rput{0}(40,5){\psellipse[linewidth=0.15,fillstyle=solid](0,0)(0.5,0.5)}
\rput{0}(47.5,20){\psellipse[linewidth=0.15,fillstyle=solid](0,0)(0.5,0.5)}
\rput{0}(37.5,30){\psellipse[linewidth=0.15,fillstyle=solid](0,0)(0.5,0.5)}
\rput{0}(22.5,35){\psellipse[linewidth=0.15,fillstyle=solid](0,0)(0.5,0.5)}
\rput{0}(15,42.5){\psellipse[linewidth=0.15,fillstyle=solid](0,0)(0.5,0.5)}
\rput{0}(32.5,40){\psellipse[linewidth=0.15,fillstyle=solid](0,0)(0.5,0.5)}
\rput(2.5,30){$p_1$}
\rput(15,45){$p_2$}
\rput(32.5,42.5){$p_4$}
\rput(22.5,37.5){$p_3$}
\rput(37.5,32.5){$p_5$}
\rput(47.5,22.5){$p_6$}
\rput(40,7.5){$p_7$}
\rput(27.5,10){$p_8$}
\rput(17.5,25){$p_9$}
\rput(117.5,40){$p_1$}
\rput(100,32.5){$p_2$}
\rput(135,32.5){$p_9$}
\rput(110,25){$p_3$}
\rput(87.5,25){$p_4$}
\rput(105,15){$p_5$}
\rput(127.5,25){$p_6$}
\rput(145,25){$p_8$}
\rput(150,15){$p_7$}
\psline[linewidth=0.15,linestyle=dotted](10,27.5)(57.5,27.5)
\rput(55,30){$y_m$}
\rput(55,27.5){}
\psline[linewidth=0.15](120,40)(132.5,35)
\psline[linewidth=0.15](115,40)(102.5,35)
\psline[linewidth=0.15](97.5,32.5)(90,27.5)
\psline[linewidth=0.15](102.5,32.5)(107.5,27.5)
\psline[linewidth=0.15](107.5,22.5)(105,17.5)
\psline[linewidth=0.15](127.5,27.5)(132.5,32.5)
\psline[linewidth=0.15](137.5,32.5)(142.5,27.5)
\psline[linewidth=0.15](147.5,22.5)(150,17.5)
\psline[linewidth=0.15,linestyle=dotted](17.5,38.75)(41.25,38.75)
\psline[linewidth=0.15,linestyle=dotted](25,15)(50,15)
\end{pspicture}
\]

\paragraph{Queries.} We search for $y_{\text{min}}$, $y_{\text{max}}$. Intuitively, we want to check all points along both search paths to see if they lie in the query region. More precisely, if $v_{\text{split}}$ is the point where the two paths diverge, we go from $v_{\text{split}}$ to $y_{\text{min}}$, reporting all right subtrees recursively, and stopping if we reach a node with $x$-coordinate greater than $x_{\text{max}}$.

A priority search tree has the following characteristics:
\begin{itemize}
\item\emph{Preprocessing:} $O(n\log n)$ to sort the $x$ and $y$ coordinates
\item\emph{Storage:} $O(n)$
\item\emph{Query:} $O(\log n+k)$
\end{itemize}

As indicated earlier, we can modify an interval tree to store a priority search tree in each node, instead of sorted lists. This structure solves Part B for orthogonal line segments. If the line segments are not orthogonal, we can use segment trees instead (homework).

\bibliographystyle{alpha}
\begin{thebibliography}{77}

\bibitem{overmars}
M. H. Overmars, \textit{The design of dynamic data structures}, Lecture Notes in Comput. Sci., 156, Springer, Berlin, 1983.

\end{thebibliography}

\end{document}
