Path queries

This commit is contained in:
Antti H S Laaksonen 2017-02-08 22:45:17 +02:00
parent ae810e0b1c
commit acd3e21305
1 changed files with 38 additions and 70 deletions

View File

@ -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}