Path queries
This commit is contained in:
parent
ae810e0b1c
commit
acd3e21305
108
luku18.tex
108
luku18.tex
|
@ -383,18 +383,19 @@ and calculate the sum of values in $O(\log n)$ time.
|
||||||
|
|
||||||
Using a node array, we can also efficiently
|
Using a node array, we can also efficiently
|
||||||
calculate sums of values on
|
calculate sums of values on
|
||||||
paths between the root node and any other
|
paths from the root node to any other
|
||||||
node in the tree.
|
node in the tree.
|
||||||
Let us next consider a problem where our task
|
Let us next consider a problem where our task
|
||||||
is to support the following queries:
|
is to support the following queries:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item change the value of a node
|
\item change the value of a node
|
||||||
\item calculate the sum of values on a path between
|
\item calculate the sum of values on a path from
|
||||||
the root node and a node
|
the root to a node
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
For example, in the following tree, the sum of
|
For example, in the following tree,
|
||||||
values from the root to node 8 is $4+5+3=12$.
|
the sum of values from the root no node 7 is
|
||||||
|
$4+5+5=14$:
|
||||||
|
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.9]
|
\begin{tikzpicture}[scale=0.9]
|
||||||
|
@ -429,21 +430,13 @@ values from the root to node 8 is $4+5+3=12$.
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
To solve this problem, we can use a similar
|
We can solve this problem in a similar way as before,
|
||||||
technique as we used for subtree queries,
|
but each value in the last row of the node array is the sum of values
|
||||||
but the values of the nodes are stored
|
on a path from the root to a node.
|
||||||
in a special way:
|
|
||||||
if the value of a node at position $k$
|
|
||||||
increases by $a$,
|
|
||||||
the value at position $k$ increases by $a$
|
|
||||||
and the value at position $k+c$ decreases by $a$,
|
|
||||||
where $c$ is the size of the subtree.
|
|
||||||
|
|
||||||
\begin{samepage}
|
|
||||||
For example, the following array corresponds to the above tree:
|
For example, the following array corresponds to the above tree:
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.7]
|
\begin{tikzpicture}[scale=0.7]
|
||||||
\draw (0,1) grid (10,-2);
|
\draw (0,1) grid (9,-2);
|
||||||
|
|
||||||
\node at (0.5,0.5) {$1$};
|
\node at (0.5,0.5) {$1$};
|
||||||
\node at (1.5,0.5) {$2$};
|
\node at (1.5,0.5) {$2$};
|
||||||
|
@ -454,7 +447,6 @@ For example, the following array corresponds to the above tree:
|
||||||
\node at (6.5,0.5) {$8$};
|
\node at (6.5,0.5) {$8$};
|
||||||
\node at (7.5,0.5) {$9$};
|
\node at (7.5,0.5) {$9$};
|
||||||
\node at (8.5,0.5) {$5$};
|
\node at (8.5,0.5) {$5$};
|
||||||
\node at (9.5,0.5) {--};
|
|
||||||
|
|
||||||
\node at (0.5,-0.5) {$9$};
|
\node at (0.5,-0.5) {$9$};
|
||||||
\node at (1.5,-0.5) {$2$};
|
\node at (1.5,-0.5) {$2$};
|
||||||
|
@ -465,18 +457,16 @@ For example, the following array corresponds to the above tree:
|
||||||
\node at (6.5,-0.5) {$1$};
|
\node at (6.5,-0.5) {$1$};
|
||||||
\node at (7.5,-0.5) {$1$};
|
\node at (7.5,-0.5) {$1$};
|
||||||
\node at (8.5,-0.5) {$1$};
|
\node at (8.5,-0.5) {$1$};
|
||||||
\node at (9.5,-0.5) {--};
|
|
||||||
|
|
||||||
\node at (0.5,-1.5) {$4$};
|
\node at (0.5,-1.5) {$4$};
|
||||||
\node at (1.5,-1.5) {$5$};
|
\node at (1.5,-1.5) {$9$};
|
||||||
\node at (2.5,-1.5) {$3$};
|
\node at (2.5,-1.5) {$12$};
|
||||||
\node at (3.5,-1.5) {$-5$};
|
\node at (3.5,-1.5) {$7$};
|
||||||
\node at (4.5,-1.5) {$2$};
|
\node at (4.5,-1.5) {$9$};
|
||||||
\node at (5.5,-1.5) {$5$};
|
\node at (5.5,-1.5) {$14$};
|
||||||
\node at (6.5,-1.5) {$-2$};
|
\node at (6.5,-1.5) {$12$};
|
||||||
\node at (7.5,-1.5) {$-2$};
|
\node at (7.5,-1.5) {$10$};
|
||||||
\node at (8.5,-1.5) {$-4$};
|
\node at (8.5,-1.5) {$6$};
|
||||||
\node at (9.5,-1.5) {$-4$};
|
|
||||||
|
|
||||||
\footnotesize
|
\footnotesize
|
||||||
\node at (0.5,1.4) {$1$};
|
\node at (0.5,1.4) {$1$};
|
||||||
|
@ -488,30 +478,18 @@ For example, the following array corresponds to the above tree:
|
||||||
\node at (6.5,1.4) {$7$};
|
\node at (6.5,1.4) {$7$};
|
||||||
\node at (7.5,1.4) {$8$};
|
\node at (7.5,1.4) {$8$};
|
||||||
\node at (8.5,1.4) {$9$};
|
\node at (8.5,1.4) {$9$};
|
||||||
\node at (9.5,1.4) {$10$};
|
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
\end{samepage}
|
|
||||||
|
|
||||||
For example, the value of node $3$ is $-5$,
|
When the value of a node increases by $x$,
|
||||||
because it is the next node after the subtrees
|
the sums of all nodes in its subtree increase by $x$.
|
||||||
of nodes $2$ and $6$ and its own value is $3$.
|
For example, if the value of node 4 increases by 1,
|
||||||
So the value decreases by $5+3$ and increases by $3$.
|
the node array changes as follows:
|
||||||
Note that the array contains an extra index 10
|
|
||||||
that only has the opposite number of the value
|
|
||||||
of the root node.
|
|
||||||
|
|
||||||
Using this array, the sum of values in a path
|
|
||||||
from the root to node $x$ equals the sum
|
|
||||||
of values in the array from the beginning to node $x$.
|
|
||||||
For example, the sum from the root to node $8$
|
|
||||||
can be calculated as follows:
|
|
||||||
|
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.7]
|
\begin{tikzpicture}[scale=0.7]
|
||||||
\fill[color=lightgray] (6,1) rectangle (7,0);
|
\fill[color=lightgray] (4,-1) rectangle (8,-2);
|
||||||
\fill[color=lightgray] (0,-1) rectangle (7,-2);
|
\draw (0,1) grid (9,-2);
|
||||||
\draw (0,1) grid (10,-2);
|
|
||||||
|
|
||||||
\node at (0.5,0.5) {$1$};
|
\node at (0.5,0.5) {$1$};
|
||||||
\node at (1.5,0.5) {$2$};
|
\node at (1.5,0.5) {$2$};
|
||||||
|
@ -522,7 +500,6 @@ can be calculated as follows:
|
||||||
\node at (6.5,0.5) {$8$};
|
\node at (6.5,0.5) {$8$};
|
||||||
\node at (7.5,0.5) {$9$};
|
\node at (7.5,0.5) {$9$};
|
||||||
\node at (8.5,0.5) {$5$};
|
\node at (8.5,0.5) {$5$};
|
||||||
\node at (9.5,0.5) {--};
|
|
||||||
|
|
||||||
\node at (0.5,-0.5) {$9$};
|
\node at (0.5,-0.5) {$9$};
|
||||||
\node at (1.5,-0.5) {$2$};
|
\node at (1.5,-0.5) {$2$};
|
||||||
|
@ -533,18 +510,16 @@ can be calculated as follows:
|
||||||
\node at (6.5,-0.5) {$1$};
|
\node at (6.5,-0.5) {$1$};
|
||||||
\node at (7.5,-0.5) {$1$};
|
\node at (7.5,-0.5) {$1$};
|
||||||
\node at (8.5,-0.5) {$1$};
|
\node at (8.5,-0.5) {$1$};
|
||||||
\node at (9.5,-0.5) {--};
|
|
||||||
|
|
||||||
\node at (0.5,-1.5) {$4$};
|
\node at (0.5,-1.5) {$4$};
|
||||||
\node at (1.5,-1.5) {$5$};
|
\node at (1.5,-1.5) {$9$};
|
||||||
\node at (2.5,-1.5) {$3$};
|
\node at (2.5,-1.5) {$12$};
|
||||||
\node at (3.5,-1.5) {$-5$};
|
\node at (3.5,-1.5) {$7$};
|
||||||
\node at (4.5,-1.5) {$2$};
|
\node at (4.5,-1.5) {$10$};
|
||||||
\node at (5.5,-1.5) {$5$};
|
\node at (5.5,-1.5) {$15$};
|
||||||
\node at (6.5,-1.5) {$-2$};
|
\node at (6.5,-1.5) {$13$};
|
||||||
\node at (7.5,-1.5) {$-2$};
|
\node at (7.5,-1.5) {$11$};
|
||||||
\node at (8.5,-1.5) {$-4$};
|
\node at (8.5,-1.5) {$6$};
|
||||||
\node at (9.5,-1.5) {$-4$};
|
|
||||||
|
|
||||||
\footnotesize
|
\footnotesize
|
||||||
\node at (0.5,1.4) {$1$};
|
\node at (0.5,1.4) {$1$};
|
||||||
|
@ -556,22 +531,15 @@ can be calculated as follows:
|
||||||
\node at (6.5,1.4) {$7$};
|
\node at (6.5,1.4) {$7$};
|
||||||
\node at (7.5,1.4) {$8$};
|
\node at (7.5,1.4) {$8$};
|
||||||
\node at (8.5,1.4) {$9$};
|
\node at (8.5,1.4) {$9$};
|
||||||
\node at (9.5,1.4) {$10$};
|
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
The sum is
|
|
||||||
\[4+5+3-5+2+5-2=12\]
|
|
||||||
that equals the sum $4+5+3=12$.
|
|
||||||
This method works, because the value of each node
|
|
||||||
is added to the sum when the depth-first search
|
|
||||||
visits the node for the first time, and the value
|
|
||||||
of the node is removed from the sum when the subtree of the
|
|
||||||
node has been processed.
|
|
||||||
|
|
||||||
Once again, we can store the values of the nodes
|
Thus, to support both the operations,
|
||||||
in a binary indexed tree or a segment tree,
|
we should be able to increase all values
|
||||||
so it is possible to both update a value and
|
in a range and retrieve a single value.
|
||||||
calculate the sum of values efficiently in $O(\log n)$ time.
|
This can be done in $O(\log n)$ time
|
||||||
|
(see Chapter 9.4) using a binary indexed tree
|
||||||
|
or segment tree.
|
||||||
|
|
||||||
\section{Lowest common ancestor}
|
\section{Lowest common ancestor}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue