Corrections
This commit is contained in:
		
							parent
							
								
									660e6f6e14
								
							
						
					
					
						commit
						1319f46f0e
					
				
							
								
								
									
										143
									
								
								luku09.tex
								
								
								
								
							
							
						
						
									
										143
									
								
								luku09.tex
								
								
								
								
							| 
						 | 
					@ -5,16 +5,15 @@
 | 
				
			||||||
\index{minimum query}
 | 
					\index{minimum query}
 | 
				
			||||||
\index{maximum query}
 | 
					\index{maximum query}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
In a \key{range query}, a range of an array
 | 
					A \key{range query} asks to calculate some information
 | 
				
			||||||
is given and we should calculate some value from the
 | 
					about the elements in a given range of an array.
 | 
				
			||||||
elements in the range. Typical range queries are:
 | 
					Typical range queries are:
 | 
				
			||||||
\begin{itemize}
 | 
					\begin{itemize}
 | 
				
			||||||
\item \key{sum query}: calculate the sum of elements in range $[a,b]$
 | 
					\item \key{sum query}: calculate the sum of elements in a range
 | 
				
			||||||
\item \key{minimum query}: find the smallest element in range $[a,b]$
 | 
					\item \key{minimum query}: find the smallest element in a range
 | 
				
			||||||
\item \key{maximum query}: find the largest element in range $[a,b]$
 | 
					\item \key{maximum query}: find the largest element in a range
 | 
				
			||||||
\end{itemize}
 | 
					\end{itemize}
 | 
				
			||||||
For example, in range $[4,7]$ of the following array,
 | 
					For example, consider the range $[4,7]$ in the following array:
 | 
				
			||||||
the sum is $4+6+1+3=14$, the minimum is 1 and the maximum is 6:
 | 
					 | 
				
			||||||
\begin{center}
 | 
					\begin{center}
 | 
				
			||||||
\begin{tikzpicture}[scale=0.7]
 | 
					\begin{tikzpicture}[scale=0.7]
 | 
				
			||||||
\fill[color=lightgray] (3,0) rectangle (7,1);
 | 
					\fill[color=lightgray] (3,0) rectangle (7,1);
 | 
				
			||||||
| 
						 | 
					@ -40,10 +39,14 @@ the sum is $4+6+1+3=14$, the minimum is 1 and the maximum is 6:
 | 
				
			||||||
\node at (7.5,1.4) {$8$};
 | 
					\node at (7.5,1.4) {$8$};
 | 
				
			||||||
\end{tikzpicture}
 | 
					\end{tikzpicture}
 | 
				
			||||||
\end{center}
 | 
					\end{center}
 | 
				
			||||||
 | 
					In this range, the sum of elements is $4+6+1+3=16$,
 | 
				
			||||||
 | 
					the minimum element is 1 and the maximum element is 6.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
An easy way to answer a range query is
 | 
					
 | 
				
			||||||
to iterate through all the elements in the range.
 | 
					An easy way to process range queries is
 | 
				
			||||||
For example, we can answer a sum query as follows:
 | 
					to go through all the elements in the range.
 | 
				
			||||||
 | 
					For example, we can calculate the sum
 | 
				
			||||||
 | 
					in a range $[a,b]$ as follows:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
\begin{lstlisting}
 | 
					\begin{lstlisting}
 | 
				
			||||||
int sum(int a, int b) {
 | 
					int sum(int a, int b) {
 | 
				
			||||||
| 
						 | 
					@ -55,34 +58,34 @@ int sum(int a, int b) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
\end{lstlisting}
 | 
					\end{lstlisting}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The above function handles a sum query
 | 
					The above function works in $O(n)$ time.
 | 
				
			||||||
in $O(n)$ time, which is slow if the array is large
 | 
					However, if the array is large and there are several queries,
 | 
				
			||||||
and there are a lot of queries.
 | 
					such an approach is slow.
 | 
				
			||||||
In this chapter we will learn how
 | 
					In this chapter, we will learn how
 | 
				
			||||||
range queries can be answered much more efficiently.
 | 
					range queries can be processed much more efficiently.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
\section{Static array queries}
 | 
					\section{Static array queries}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
We will first focus on a simple case where
 | 
					We first focus on a simple situation where
 | 
				
			||||||
the array is \key{static}, i.e.,
 | 
					the array is \key{static}, i.e.,
 | 
				
			||||||
the elements never change between the queries.
 | 
					the elements never change between the queries.
 | 
				
			||||||
In this case, it suffices to process the
 | 
					In this case, it suffices to preprocess the
 | 
				
			||||||
contents of the array beforehand and construct
 | 
					array and construct
 | 
				
			||||||
a data structure that can be used for answering
 | 
					a data structure that can be used for
 | 
				
			||||||
 | 
					finding the answer for
 | 
				
			||||||
any possible range query efficiently.
 | 
					any possible range query efficiently.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
\subsubsection{Sum query}
 | 
					\subsubsection{Sum query}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
\index{prefix sum array}
 | 
					\index{prefix sum array}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Sum queries can be answered efficiently
 | 
					Sum queries can be processed efficiently
 | 
				
			||||||
by constructing a \key{sum array}
 | 
					by constructing a \key{sum array}
 | 
				
			||||||
that contains the sum of the range $[1,k]$
 | 
					that contains the sum of elements in the range $[1,k]$
 | 
				
			||||||
for each $k=1,2,\ldots,n$.
 | 
					for each $k=1,2,\ldots,n$.
 | 
				
			||||||
After this, the sum of any range $[a,b]$ of the
 | 
					Using the sum array, the sum of elements in
 | 
				
			||||||
original array
 | 
					any range $[a,b]$ of the original array can
 | 
				
			||||||
can be calculated in $O(1)$ time using the
 | 
					be calculated in $O(1)$ time.
 | 
				
			||||||
precalculated sum array.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
For example, for the array
 | 
					For example, for the array
 | 
				
			||||||
\begin{center}
 | 
					\begin{center}
 | 
				
			||||||
| 
						 | 
					@ -137,27 +140,27 @@ the corresponding sum array is as follows:
 | 
				
			||||||
\node at (7.5,1.4) {$8$};
 | 
					\node at (7.5,1.4) {$8$};
 | 
				
			||||||
\end{tikzpicture}
 | 
					\end{tikzpicture}
 | 
				
			||||||
\end{center}
 | 
					\end{center}
 | 
				
			||||||
The following code constructs a prefix sum
 | 
					The following code constructs a sum array
 | 
				
			||||||
array \texttt{s} from array \texttt{t} in $O(n)$ time:
 | 
					\texttt{s} for an array \texttt{t} in $O(n)$ time:
 | 
				
			||||||
\begin{lstlisting}
 | 
					\begin{lstlisting}
 | 
				
			||||||
for (int i = 1; i <= n; i++) {
 | 
					for (int i = 1; i <= n; i++) {
 | 
				
			||||||
    s[i] = s[i-1]+t[i];
 | 
					    s[i] = s[i-1]+t[i];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
\end{lstlisting}
 | 
					\end{lstlisting}
 | 
				
			||||||
After this, the following function answers
 | 
					After this, the following function processes
 | 
				
			||||||
a sum query in $O(1)$ time:
 | 
					any sum query in $O(1)$ time:
 | 
				
			||||||
\begin{lstlisting}
 | 
					\begin{lstlisting}
 | 
				
			||||||
int sum(int a, int b) {
 | 
					int sum(int a, int b) {
 | 
				
			||||||
    return s[b]-s[a-1];
 | 
					    return s[b]-s[a-1];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
\end{lstlisting}
 | 
					\end{lstlisting}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The function calculates the sum of range $[a,b]$
 | 
					The function calculates the sum in the range $[a,b]$
 | 
				
			||||||
by subtracting the sum of range $[1,a-1]$
 | 
					by subtracting the sum in the range $[1,a-1]$
 | 
				
			||||||
from the sum of range $[1,b]$.
 | 
					from the sum in the range $[1,b]$.
 | 
				
			||||||
Thus, only two values from the sum array
 | 
					Thus, only two values of the sum array
 | 
				
			||||||
are needed, and the query takes $O(1)$ time.
 | 
					are needed, and the query takes $O(1)$ time.
 | 
				
			||||||
Note that thanks to the one-based indexing,
 | 
					Note that because of the one-based indexing,
 | 
				
			||||||
the function also works when $a=1$ if $\texttt{s}[0]=0$. 
 | 
					the function also works when $a=1$ if $\texttt{s}[0]=0$. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
As an example, consider the range $[4,7]$:
 | 
					As an example, consider the range $[4,7]$:
 | 
				
			||||||
| 
						 | 
					@ -186,9 +189,9 @@ As an example, consider the range $[4,7]$:
 | 
				
			||||||
\node at (7.5,1.4) {$8$};
 | 
					\node at (7.5,1.4) {$8$};
 | 
				
			||||||
\end{tikzpicture}
 | 
					\end{tikzpicture}
 | 
				
			||||||
\end{center}
 | 
					\end{center}
 | 
				
			||||||
The sum of the range $[4,7]$ is $8+6+1+4=19$.
 | 
					The sum in the range is $8+6+1+4=19$.
 | 
				
			||||||
This can be calculated from the sum array
 | 
					This can be calculated using the precalculated
 | 
				
			||||||
using the sums $[1,3]$ and $[1,7]$:
 | 
					sums for the ranges $[1,3]$ and $[1,7]$:
 | 
				
			||||||
\begin{center}
 | 
					\begin{center}
 | 
				
			||||||
\begin{tikzpicture}[scale=0.7]
 | 
					\begin{tikzpicture}[scale=0.7]
 | 
				
			||||||
\fill[color=lightgray] (2,0) rectangle (3,1);
 | 
					\fill[color=lightgray] (2,0) rectangle (3,1);
 | 
				
			||||||
| 
						 | 
					@ -216,14 +219,15 @@ using the sums $[1,3]$ and $[1,7]$:
 | 
				
			||||||
\node at (7.5,1.4) {$8$};
 | 
					\node at (7.5,1.4) {$8$};
 | 
				
			||||||
\end{tikzpicture}
 | 
					\end{tikzpicture}
 | 
				
			||||||
\end{center}
 | 
					\end{center}
 | 
				
			||||||
Thus, the sum of the range $[4,7]$ is $27-8=19$.
 | 
					Thus, the sum in the range $[4,7]$ is $27-8=19$.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
We can also generalize the idea of a sum array
 | 
					It is also possible to generalize this idea
 | 
				
			||||||
for a two-dimensional array.
 | 
					to higher dimensions.
 | 
				
			||||||
In this case, it will be possible to calculate the sum of
 | 
					For example, we can construct a two-dimensional
 | 
				
			||||||
any rectangular subarray in $O(1)$ time.
 | 
					sum array that can be used for calculating
 | 
				
			||||||
The sum array will contain sums
 | 
					the sum of any rectangular subarray in $O(1)$ time.
 | 
				
			||||||
for all subarrays that begin from the upper-left corner.
 | 
					Each value in such an array is the sum of a subarray
 | 
				
			||||||
 | 
					that begins at the upper-left corner of the array.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
\begin{samepage}
 | 
					\begin{samepage}
 | 
				
			||||||
The following picture illustrates the idea:
 | 
					The following picture illustrates the idea:
 | 
				
			||||||
| 
						 | 
					@ -240,23 +244,23 @@ The following picture illustrates the idea:
 | 
				
			||||||
\end{center}
 | 
					\end{center}
 | 
				
			||||||
\end{samepage}
 | 
					\end{samepage}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The sum inside the gray subarray can be calculated
 | 
					The sum of the gray subarray can be calculated
 | 
				
			||||||
using the formula
 | 
					using the formula
 | 
				
			||||||
\[S(A) - S(B) - S(C) + S(D)\]
 | 
					\[S(A) - S(B) - S(C) + S(D),\]
 | 
				
			||||||
where $S(X)$ denotes the sum in a rectangular
 | 
					where $S(X)$ denotes the sum of a rectangular
 | 
				
			||||||
subarray from the upper-left corner
 | 
					subarray from the upper-left corner
 | 
				
			||||||
to the position of letter $X$.
 | 
					to the position of $X$.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
\subsubsection{Minimum query}
 | 
					\subsubsection{Minimum query}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
It is also possible to answer a minimum query
 | 
					It is also possible to process minimum queries
 | 
				
			||||||
in $O(1)$ time after preprocessing, though it is
 | 
					in $O(1)$ time after preprocessing, though it is
 | 
				
			||||||
more difficult than answer a sum query.
 | 
					more difficult than processing sum queries.
 | 
				
			||||||
Note that minimum and maximum queries can always
 | 
					Note that minimum and maximum queries can always
 | 
				
			||||||
be implemented using same techniques,
 | 
					be implemented using same techniques,
 | 
				
			||||||
so it suffices to focus on the minimum query.
 | 
					so it suffices to focus on minimum queries.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The idea is to find the minimum element for each range
 | 
					The idea is to precalculate the minimum element of each range
 | 
				
			||||||
of size $2^k$ in the array.
 | 
					of size $2^k$ in the array.
 | 
				
			||||||
For example, in the array
 | 
					For example, in the array
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -336,21 +340,22 @@ $[1,8]$ & 8 & 1 \\
 | 
				
			||||||
 | 
					
 | 
				
			||||||
\end{center}
 | 
					\end{center}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The number of $2^k$ ranges in an array is $O(n \log n)$
 | 
					There are $O(n \log n)$ ranges of size $2^k$,
 | 
				
			||||||
because there are $O(\log n)$ ranges that begin
 | 
					because for each array position,
 | 
				
			||||||
from each array index.
 | 
					there are $O(\log n)$ ranges that begin at that position.
 | 
				
			||||||
The minima for all $2^k$ ranges can be calculated
 | 
					The minima in all ranges of size $2^k$ can be calculated
 | 
				
			||||||
in $O(n \log n)$ time because each $2^k$ range
 | 
					in $O(n \log n)$ time, because each range of size $2^k$
 | 
				
			||||||
consists of two $2^{k-1}$ ranges, so the minima
 | 
					consists of two ranges of size $2^{k-1}$ and the minima
 | 
				
			||||||
can be calculated recursively.
 | 
					can be calculated recursively.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
After this, the minimum of any range $[a,b]$c
 | 
					After this, the minimum in any range $[a,b]$
 | 
				
			||||||
can be calculated in $O(1)$ time as a minimum of
 | 
					can be calculated in $O(1)$ time as a minimum of
 | 
				
			||||||
two $2^k$ ranges where $k=\lfloor \log_2(b-a+1) \rfloor$.
 | 
					two ranges of size $2^k$ where $k=\lfloor \log_2(b-a+1) \rfloor$.
 | 
				
			||||||
The first range begins from index $a$,
 | 
					The first range begins at index $a$,
 | 
				
			||||||
and the second range ends to index $b$.
 | 
					and the second range ends at index $b$.
 | 
				
			||||||
The parameter $k$ is so chosen that
 | 
					The parameter $k$ is chosen so that
 | 
				
			||||||
two $2^k$ ranges cover the range $[a,b]$ entirely.
 | 
					the two ranges of size $2^k$
 | 
				
			||||||
 | 
					fully cover the range $[a,b]$.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
As an example, consider the range $[2,7]$:
 | 
					As an example, consider the range $[2,7]$:
 | 
				
			||||||
\begin{center}
 | 
					\begin{center}
 | 
				
			||||||
| 
						 | 
					@ -378,7 +383,7 @@ As an example, consider the range $[2,7]$:
 | 
				
			||||||
\node at (7.5,1.4) {$8$};
 | 
					\node at (7.5,1.4) {$8$};
 | 
				
			||||||
\end{tikzpicture}
 | 
					\end{tikzpicture}
 | 
				
			||||||
\end{center}
 | 
					\end{center}
 | 
				
			||||||
The length of the range $[2,7]$ is 6,
 | 
					The length of the range is 6,
 | 
				
			||||||
and $\lfloor \log_2(6) \rfloor = 2$.
 | 
					and $\lfloor \log_2(6) \rfloor = 2$.
 | 
				
			||||||
Thus, the minimum can be calculated
 | 
					Thus, the minimum can be calculated
 | 
				
			||||||
from two ranges of length 4.
 | 
					from two ranges of length 4.
 | 
				
			||||||
| 
						 | 
					@ -434,9 +439,9 @@ The ranges are $[2,5]$ and $[4,7]$:
 | 
				
			||||||
\node at (7.5,1.4) {$8$};
 | 
					\node at (7.5,1.4) {$8$};
 | 
				
			||||||
\end{tikzpicture}
 | 
					\end{tikzpicture}
 | 
				
			||||||
\end{center}
 | 
					\end{center}
 | 
				
			||||||
The minimum of the range $[2,5]$ is 3,
 | 
					Since the minimum in the range $[2,5]$ is 3
 | 
				
			||||||
and the minimum of the range $[4,7]$ is 1.
 | 
					and the minimum in the range $[4,7]$ is 1,
 | 
				
			||||||
Thus, the minimum of the range $[2,7]$ is 1.
 | 
					we know that the minimum in the range $[2,7]$ is 1.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
\section{Binary indexed tree}
 | 
					\section{Binary indexed tree}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue