Corrections

This commit is contained in:
Antti H S Laaksonen 2017-02-04 11:48:16 +02:00
parent 1319f46f0e
commit d71d3957fb
1 changed files with 58 additions and 55 deletions

View File

@ -448,31 +448,33 @@ we know that the minimum in the range $[2,7]$ is 1.
\index{binary indexed tree} \index{binary indexed tree}
\index{Fenwick tree} \index{Fenwick tree}
A \key{binary indexed tree} or a \key{Fenwick tree} A \key{binary indexed tree} or \key{Fenwick tree}
is a data structure that resembles a sum array. can be seen as a dynamic version of a sum array.
The supported operations are answering The tree supports two $O(\log n)$ time operations:
a sum query for range $[a,b]$, calculating the sum of elements in a range,
and updating the element at index $k$. and modifying the value of an element.
The time complexity for both of the operations is $O(\log n)$.
Unlike a sum array, a binary indexed tree The benefit in using a binary indexed tree is
can be efficiently updated between the sum queries. that the elements of the underlying array
This would not be possible using a sum array can be efficiently updated between the queries.
because we should build the whole sum array again This would not be possible with a sum array,
in $O(n)$ time after each update. because after each update, we should build the
whole sum array again in $O(n)$ time.
\subsubsection{Structure} \subsubsection{Structure}
A binary indexed tree can be represented as an array Given an array of $n$ elements, indexed $1 \ldots n$,
where index $k$ contains the sum of a range in the the binary indexed tree for that array
original array that ends to index $k$. is an array such that the value at position $k$
equals the sum of elements in the original array in a range
that ends at position $k$.
The length of the range is the largest power of two The length of the range is the largest power of two
that divides $k$. that divides $k$.
For example, if $k=6$, the length of the range is $2$ For example, if $k=6$, the length of the range is $2$,
because $2$ divides $6$ but $4$ doesn't divide $6$. because $2$ divides $6$ but $4$ does not divide $6$.
\begin{samepage} \begin{samepage}
For example, for the array For example, consider the following array:
\begin{center} \begin{center}
\begin{tikzpicture}[scale=0.7] \begin{tikzpicture}[scale=0.7]
\draw (0,0) grid (8,1); \draw (0,0) grid (8,1);
@ -498,7 +500,7 @@ For example, for the array
\end{tikzpicture} \end{tikzpicture}
\end{center} \end{center}
\end{samepage} \end{samepage}
the corresponding binary indexed tree is as follows: The corresponding binary indexed tree is as follows:
\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);
@ -543,21 +545,21 @@ the corresponding binary indexed tree is as follows:
\end{tikzpicture} \end{tikzpicture}
\end{center} \end{center}
For example, the binary indexed tree For example, the value at position 6
contains the value 7 at index 6 in the binary indexed tree is 7,
because the sum of the elements in the range $[5,6]$ because the sum of elements in the range $[5,6]$
of the original array is $6+1=7$. in the original array is $6+1=7$.
\subsubsection{Sum query} \subsubsection{Sum query}
The basic operation in a binary indexed tree is The basic operation in a binary indexed tree is
calculating the sum of a range $[1,k]$ where $k$ to calculate the sum of elements in a range $[1,k]$,
is any index in the array. where $k$ is any position in the array.
The sum of any range can be constructed by combining The sum of such a range can be calculated as a
sums of subranges in the tree. sum of one or more values stored in the tree.
For example, the range $[1,7]$ will be divided For example, the range $[1,7]$ corresponds to
into three subranges: the following values:
\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);
@ -602,25 +604,24 @@ into three subranges:
\end{tikzpicture} \end{tikzpicture}
\end{center} \end{center}
Thus, the sum of the range $[1,7]$ is $16+7+4=27$. Hence, the sum of elements in the range $[1,7]$ is $16+7+4=27$.
Because of the structure of the binary indexed tree, The structure of the binary indexed tree allows us to calculate
the length of each subrange inside a range is distinct, the sum of elements in any range using only $O(\log n)$
so the sum of a range values from the tree.
always consists of sums of $O(\log n)$ subranges.
Using the same technique that we previously used Using the same technique that we previously used
with a sum array, with a sum array,
we can efficiently calculate the sum of any range we can efficiently calculate the sum of any range
$[a,b]$ by substracting the sum of the range $[1,a-1]$ $[a,b]$ by substracting the sum of the range $[1,a-1]$
from the sum of the range $[1,b]$. from the sum of the range $[1,b]$.
The time complexity remains $O(\log n)$ Also here, only $O(\log n)$ values are needed,
because it suffices to calculate two sums of $[1,k]$ ranges. because it suffices to calculate two sums of $[1,k]$ ranges.
\subsubsection{Array update} \subsubsection{Array update}
When an element in the original array changes, When an element in the original array changes,
several sums in the binary indexed tree change. several sums in the binary indexed tree change.
For example, if the value at index 3 changes, For example, if the element at position 3 changes,
the sums of the following ranges change: the sums of the following ranges change:
\begin{center} \begin{center}
\begin{tikzpicture}[scale=0.7] \begin{tikzpicture}[scale=0.7]
@ -666,28 +667,28 @@ the sums of the following ranges change:
\end{tikzpicture} \end{tikzpicture}
\end{center} \end{center}
Also in this case, the length of each range is distinct, However, it turns out that
so $O(\log n)$ ranges will be updated in the binary indexed tree. the number of values that need to be updated
in the binary indexed tree is only $O(\log n)$.
\subsubsection{Implementation} \subsubsection{Implementation}
The operations of a binary indexed tree can be implemented The operations of a binary indexed tree can be implemented
in an elegant and efficient way using bit manipulation. in an elegant and efficient way using bit operations.
The bit operation needed is $k \& -k$ that The key fact needed is that $k \& -k$
returns the last bit one from number $k$. isolates the last one bit in a number $k$.
For example, $6 \& -6=2$ because the number $6$ For example, $6 \& -6=2$ because the number $6$
corresponds to 110 and the number $2$ corresponds to 10. corresponds to 110 and the number $2$ corresponds to 10.
It turns out that when calculating a range sum, It turns out that when processing a range query,
the index $k$ in the binary indexed tree should be the position $k$ in the binary indexed tree should be
decreased by $k \& -k$ at every step. decreased by $k \& -k$ at every step,
Correspondingly, when updating the array, and when updating the array,
the index $k$ should be increased by $k \& -k$ at every step. the position $k$ should be increased by $k \& -k$ at every step.
The following functions assume that the binary indexed tree Suppose that the binary indexed tree is stored in an array \texttt{b}.
is stored to array \texttt{b} and it consists of indices $1 \ldots n$. The following function \texttt{sum} calculates
the sum of elements in the range $[1,k]$:
The function \texttt{sum} calculates the sum of the range $[1,k]$:
\begin{lstlisting} \begin{lstlisting}
int sum(int k) { int sum(int k) {
int s = 0; int s = 0;
@ -699,7 +700,9 @@ int sum(int k) {
} }
\end{lstlisting} \end{lstlisting}
The function \texttt{add} increases the value of element $k$ by $x$: The following function \texttt{add} increases the value
of the element at position $k$ by $x$
($x$ can be positive or negative):
\begin{lstlisting} \begin{lstlisting}
void add(int k, int x) { void add(int k, int x) {
while (k <= n) { while (k <= n) {
@ -709,11 +712,11 @@ void add(int k, int x) {
} }
\end{lstlisting} \end{lstlisting}
The time complexity of both above functions is The time complexity of both the functions is
$O(\log n)$ because the functions change $O(\log n)$ $O(\log n)$, because the functions access $O(\log n)$
values in the binary indexed tree and each move values in the binary indexed tree, and each transition
to the next index to the next position
takes $O(1)$ time using the bit operation. takes $O(1)$ time using bit operations.
\section{Segment tree} \section{Segment tree}