Corrections
This commit is contained in:
parent
d71d3957fb
commit
b2931ed5da
268
luku09.tex
268
luku09.tex
|
@ -687,8 +687,8 @@ and when updating the array,
|
||||||
the position $k$ should be increased by $k \& -k$ at every step.
|
the position $k$ should be increased by $k \& -k$ at every step.
|
||||||
|
|
||||||
Suppose that the binary indexed tree is stored in an array \texttt{b}.
|
Suppose that the binary indexed tree is stored in an array \texttt{b}.
|
||||||
The following function \texttt{sum} calculates
|
The following function calculates
|
||||||
the sum of elements in the range $[1,k]$:
|
the sum of elements in a range $[1,k]$:
|
||||||
\begin{lstlisting}
|
\begin{lstlisting}
|
||||||
int sum(int k) {
|
int sum(int k) {
|
||||||
int s = 0;
|
int s = 0;
|
||||||
|
@ -700,7 +700,7 @@ int sum(int k) {
|
||||||
}
|
}
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
The following function \texttt{add} increases the value
|
The following function increases the value
|
||||||
of the element at position $k$ by $x$
|
of the element at position $k$ by $x$
|
||||||
($x$ can be positive or negative):
|
($x$ can be positive or negative):
|
||||||
\begin{lstlisting}
|
\begin{lstlisting}
|
||||||
|
@ -723,11 +723,11 @@ takes $O(1)$ time using bit operations.
|
||||||
\index{segment tree}
|
\index{segment tree}
|
||||||
|
|
||||||
A \key{segment tree} is a data structure
|
A \key{segment tree} is a data structure
|
||||||
whose supported operations are
|
that supports two operations:
|
||||||
handling a range query for range $[a,b]$
|
processing a range query and
|
||||||
and updating the element at index $k$.
|
modifying an element in the array.
|
||||||
Using a segment tree, we can implement sum
|
Segment trees can support
|
||||||
queries, minimum queries and many other
|
sum queries, minimum and maximum queries and many other
|
||||||
queries so that both operations work in $O(\log n)$ time.
|
queries so that both operations work in $O(\log n)$ time.
|
||||||
|
|
||||||
Compared to a binary indexed tree,
|
Compared to a binary indexed tree,
|
||||||
|
@ -740,16 +740,15 @@ memory and is a bit more difficult to implement.
|
||||||
|
|
||||||
\subsubsection{Structure}
|
\subsubsection{Structure}
|
||||||
|
|
||||||
A segment tree contains $2n-1$ nodes
|
A segment tree is a binary tree that
|
||||||
so that the bottom $n$ nodes correspond
|
contains $2n-1$ nodes.
|
||||||
to the original array and the other nodes
|
The nodes on the bottom level of the tree
|
||||||
contain information needed for range queries.
|
correspond to the original array,
|
||||||
The values in a segment tree depend on
|
and the other nodes
|
||||||
the supported query type.
|
contain information needed for processing range queries.
|
||||||
We will first assume that the supported
|
|
||||||
query is the sum query.
|
|
||||||
|
|
||||||
For example, the array
|
We will first discuss segment trees that support
|
||||||
|
sum queries. As an 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);
|
||||||
|
@ -763,18 +762,18 @@ For example, the array
|
||||||
\node at (6.5,0.5) {$2$};
|
\node at (6.5,0.5) {$2$};
|
||||||
\node at (7.5,0.5) {$6$};
|
\node at (7.5,0.5) {$6$};
|
||||||
|
|
||||||
\footnotesize
|
% \footnotesize
|
||||||
\node at (0.5,1.4) {$1$};
|
% \node at (0.5,1.4) {$1$};
|
||||||
\node at (1.5,1.4) {$2$};
|
% \node at (1.5,1.4) {$2$};
|
||||||
\node at (2.5,1.4) {$3$};
|
% \node at (2.5,1.4) {$3$};
|
||||||
\node at (3.5,1.4) {$4$};
|
% \node at (3.5,1.4) {$4$};
|
||||||
\node at (4.5,1.4) {$5$};
|
% \node at (4.5,1.4) {$5$};
|
||||||
\node at (5.5,1.4) {$6$};
|
% \node at (5.5,1.4) {$6$};
|
||||||
\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$};
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
corresponds to the following segment tree:
|
The corresponding segment tree is as follows:
|
||||||
\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);
|
||||||
|
@ -823,22 +822,18 @@ and it can be calculated as the sum of
|
||||||
the values of its left and right child node.
|
the values of its left and right child node.
|
||||||
|
|
||||||
It is convenient to build a segment tree
|
It is convenient to build a segment tree
|
||||||
when the size of the array is a power of two
|
for an array whose size is a power of two,
|
||||||
and the tree is a complete binary tree.
|
because in this case every internal node has a left
|
||||||
|
and right child.
|
||||||
In the sequel, we will assume that the tree
|
In the sequel, we will assume that the tree
|
||||||
is built like this.
|
is built like this.
|
||||||
If the size of the array is not a power of two,
|
If the size of the array is not a power of two,
|
||||||
we can always extend it using zero elements.
|
we can always add zero elements to the array.
|
||||||
|
|
||||||
\subsubsection{Range query}
|
\subsubsection{Range query}
|
||||||
|
|
||||||
In a segment tree, the answer for a range query
|
The sum of elements in a given range
|
||||||
is calculated from nodes that belong to the range
|
can be calculated as a sum of values in the segment tree.
|
||||||
and are as high as possible in the tree.
|
|
||||||
Each node gives the answer for a subrange,
|
|
||||||
and the answer for the entire range can be
|
|
||||||
calculated by combining these values.
|
|
||||||
|
|
||||||
For example, consider the following range:
|
For example, consider the following range:
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.7]
|
\begin{tikzpicture}[scale=0.7]
|
||||||
|
@ -853,22 +848,22 @@ For example, consider the following range:
|
||||||
\node[anchor=center] at (5.5, 0.5) {7};
|
\node[anchor=center] at (5.5, 0.5) {7};
|
||||||
\node[anchor=center] at (6.5, 0.5) {2};
|
\node[anchor=center] at (6.5, 0.5) {2};
|
||||||
\node[anchor=center] at (7.5, 0.5) {6};
|
\node[anchor=center] at (7.5, 0.5) {6};
|
||||||
|
%
|
||||||
\footnotesize
|
% \footnotesize
|
||||||
\node at (0.5,1.4) {$1$};
|
% \node at (0.5,1.4) {$1$};
|
||||||
\node at (1.5,1.4) {$2$};
|
% \node at (1.5,1.4) {$2$};
|
||||||
\node at (2.5,1.4) {$3$};
|
% \node at (2.5,1.4) {$3$};
|
||||||
\node at (3.5,1.4) {$4$};
|
% \node at (3.5,1.4) {$4$};
|
||||||
\node at (4.5,1.4) {$5$};
|
% \node at (4.5,1.4) {$5$};
|
||||||
\node at (5.5,1.4) {$6$};
|
% \node at (5.5,1.4) {$6$};
|
||||||
\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$};
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
The sum of elements in the range $[3,8]$ is
|
The sum of elements in the range is
|
||||||
$6+3+2+7+2+6=26$.
|
$6+3+2+7+2+6=26$.
|
||||||
The sum can be calculated from the segment tree
|
The following two nodes in the tree
|
||||||
using the following subranges:
|
cover the range:
|
||||||
\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);
|
||||||
|
@ -907,22 +902,23 @@ using the following subranges:
|
||||||
\path[draw,thick,-] (m) -- (j);
|
\path[draw,thick,-] (m) -- (j);
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
Thus, the sum of the range is $9+17=26$.
|
Thus, the sum of elements in the range is $9+17=26$.
|
||||||
|
|
||||||
When the answer for a range query is
|
When the sum is calculated using nodes
|
||||||
calculated using as high nodes as possible,
|
that are located as high as possible in the tree,
|
||||||
at most two nodes on each level
|
at most two nodes on each level
|
||||||
of the segment tree are needed.
|
of the tree are needed.
|
||||||
Because of this, the total number of nodes
|
Hence, the total number of nodes
|
||||||
examined is only $O(\log n)$.
|
examined is only $O(\log n)$.
|
||||||
|
|
||||||
\subsubsection{Array update}
|
\subsubsection{Array update}
|
||||||
|
|
||||||
When an element in the array changes,
|
When an element in the array changes,
|
||||||
we should update all nodes in the segment tree
|
we should update all nodes in the tree
|
||||||
whose value depends on the changed element.
|
whose value depends on the element.
|
||||||
This can be done by travelling from the bottom
|
This can be done by traversing the path
|
||||||
to the top in the tree and updating the nodes along the path.
|
from the element to the top node
|
||||||
|
and updating the nodes along the path.
|
||||||
|
|
||||||
\begin{samepage}
|
\begin{samepage}
|
||||||
The following picture shows which nodes in the segment tree
|
The following picture shows which nodes in the segment tree
|
||||||
|
@ -969,24 +965,24 @@ change if the element 7 in the array changes.
|
||||||
\end{center}
|
\end{center}
|
||||||
\end{samepage}
|
\end{samepage}
|
||||||
|
|
||||||
The path from the bottom of the segment tree to the top
|
The path from bottom to top
|
||||||
always consists of $O(\log n)$ nodes,
|
always consists of $O(\log n)$ nodes,
|
||||||
so updating the array affects $O(\log n)$ nodes in the tree.
|
so each update changes $O(\log n)$ nodes in the tree.
|
||||||
|
|
||||||
\subsubsection{Storing the tree}
|
\subsubsection{Storing the tree}
|
||||||
|
|
||||||
A segment tree can be stored as an array
|
A segment tree can be stored in an array
|
||||||
of $2N$ elements where $N$ is a power of two.
|
of $2N$ elements where $N$ is a power of two.
|
||||||
From now on, we will assume that the indices
|
From now on, we will assume that the indices
|
||||||
of the original array are between $0$ and $N-1$.
|
of the original array are between $0$ and $N-1$.
|
||||||
|
|
||||||
The element at index 1 in the segment tree array
|
The element at position 1 in the array
|
||||||
contains the top node of the tree,
|
corresponds to the top node of the tree,
|
||||||
the elements at indices 2 and 3 correspond to
|
the elements at positions 2 and 3 correspond to
|
||||||
the second level of the tree, and so on.
|
the second level of the tree, and so on.
|
||||||
Finally, the elements beginning from index $N$
|
Finally, the elements at positions $N \ldots 2N-1$
|
||||||
contain the bottom level of the tree, i.e.,
|
correspond to the bottom level of the tree, i.e.,
|
||||||
the actual content of the original array.
|
the elements of the original array.
|
||||||
|
|
||||||
For example, the segment tree
|
For example, the segment tree
|
||||||
\begin{center}
|
\begin{center}
|
||||||
|
@ -1068,11 +1064,11 @@ can be stored as follows ($N=8$):
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
Using this representation,
|
Using this representation,
|
||||||
for a node at index $k$,
|
for a node at position $k$,
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item the parent node is at index $\lfloor k/2 \rfloor$,
|
\item the parent node is at position $\lfloor k/2 \rfloor$,
|
||||||
\item the left child node is at index $2k$, and
|
\item the left child node is at position $2k$, and
|
||||||
\item the right child node is at index $2k+1$.
|
\item the right child node is at position $2k+1$.
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
Note that this implies that the index of a node
|
Note that this implies that the index of a node
|
||||||
is even if it is a left child and odd if it is a right child.
|
is even if it is a left child and odd if it is a right child.
|
||||||
|
@ -1080,8 +1076,9 @@ is even if it is a left child and odd if it is a right child.
|
||||||
\subsubsection{Functions}
|
\subsubsection{Functions}
|
||||||
|
|
||||||
We assume that the segment tree is stored
|
We assume that the segment tree is stored
|
||||||
in the array \texttt{p}.
|
in an array \texttt{p}.
|
||||||
The following function calculates the sum of range $[a,b]$:
|
The following function
|
||||||
|
calculates the sum of elements in a range $[a,b]$:
|
||||||
|
|
||||||
\begin{lstlisting}
|
\begin{lstlisting}
|
||||||
int sum(int a, int b) {
|
int sum(int a, int b) {
|
||||||
|
@ -1096,15 +1093,18 @@ int sum(int a, int b) {
|
||||||
}
|
}
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
The function begins from the bottom of the tree
|
The function maintains a range in the segment tree array.
|
||||||
and moves step by step upwards in the tree.
|
Initially the range is $[a+N,b+N]$,
|
||||||
The function calculates the range sum to
|
that corresponds to the range $[a,b]$
|
||||||
the variable $s$ by combining the sums in the tree nodes.
|
in the underlying array.
|
||||||
The value of a node is added to the sum if
|
At each step, the function adds the value of
|
||||||
the parent node doesn't belong to the range.
|
the left and right node to the sum
|
||||||
|
if their parent nodes do not belong to the range.
|
||||||
|
After this, the same process continues on the
|
||||||
|
next level of the tree.
|
||||||
|
|
||||||
The function \texttt{add} increases the value
|
The following function increases the value
|
||||||
of element $k$ by $x$:
|
of the element at position $k$ by $x$:
|
||||||
|
|
||||||
\begin{lstlisting}
|
\begin{lstlisting}
|
||||||
void add(int k, int x) {
|
void add(int k, int x) {
|
||||||
|
@ -1115,28 +1115,27 @@ void add(int k, int x) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
First the function updates the bottom level
|
First the function updates the element
|
||||||
of the tree that corresponds to the original array.
|
at the bottom level of the tree.
|
||||||
After this, the function updates the values of all
|
After this, the function updates the values of all
|
||||||
internal nodes in the tree, until it reaches
|
internal nodes in the tree, until it reaches
|
||||||
the root node of the tree.
|
the top node of the tree.
|
||||||
|
|
||||||
Both operations in the segment tree work
|
Both above functions work
|
||||||
in $O(\log n)$ time because a segment tree
|
in $O(\log n)$ time, because a segment tree
|
||||||
of $n$ elements consists of $O(\log n)$ levels,
|
of $n$ elements consists of $O(\log n)$ levels,
|
||||||
and the operations move one level forward at each step.
|
and the operations move one level forward in the tree at each step.
|
||||||
|
|
||||||
\subsubsection{Other queries}
|
\subsubsection{Other queries}
|
||||||
|
|
||||||
Besides the sum query,
|
A segment tree can support any query
|
||||||
the segment tree can support any range query
|
where the answer for a range $[a,b]$
|
||||||
where the answer for range $[a,b]$
|
can be calculated
|
||||||
can be efficiently calculated
|
from the answers for ranges $[a,c]$ and $[c+1,b]$, where
|
||||||
from ranges $[a,c]$ and $[c+1,b]$ where
|
$c$ is some index between $a$ and $b$.
|
||||||
$c$ is some element between $a$ and $b$.
|
Examples of such queries are
|
||||||
Such queries are, for example,
|
|
||||||
minimum and maximum, greatest common divisor,
|
minimum and maximum, greatest common divisor,
|
||||||
and bit operations.
|
and bit operations and, or and xor.
|
||||||
|
|
||||||
\begin{samepage}
|
\begin{samepage}
|
||||||
For example, the following segment tree
|
For example, the following segment tree
|
||||||
|
@ -1184,23 +1183,23 @@ supports minimum queries:
|
||||||
|
|
||||||
In this segment tree, every node in the tree
|
In this segment tree, every node in the tree
|
||||||
contains the smallest element in the corresponding
|
contains the smallest element in the corresponding
|
||||||
range of the original array.
|
range of the underlying array.
|
||||||
The top node of the tree contains the smallest
|
The top node of the tree contains the smallest
|
||||||
element in the array.
|
element in the whole array.
|
||||||
The tree can be implemented like previously,
|
The operations can be implemented like previously,
|
||||||
but instead of sums, minima are calculated.
|
but instead of sums, minima are calculated.
|
||||||
|
|
||||||
\subsubsection{Binary search in tree}
|
\subsubsection{Binary search in tree}
|
||||||
|
|
||||||
The structure of the segment tree makes it possible
|
The structure of the segment tree allows us
|
||||||
to use binary search.
|
to use binary search for finding elements in the array.
|
||||||
For example, if the tree supports the minimum query,
|
For example, if the tree supports the minimum query,
|
||||||
we can find the index of the smallest
|
we can find the position of the smallest
|
||||||
element in $O(\log n)$ time.
|
element in $O(\log n)$ time.
|
||||||
|
|
||||||
For example, in the following tree the
|
For example, in the following tree the
|
||||||
smallest element is 1 that can be found
|
smallest element 1 can be found
|
||||||
by following a path downwards from the top node:
|
by traversing a path downwards from the top node:
|
||||||
|
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{tikzpicture}[scale=0.7]
|
\begin{tikzpicture}[scale=0.7]
|
||||||
|
@ -1252,31 +1251,31 @@ by following a path downwards from the top node:
|
||||||
|
|
||||||
\subsubsection{Index compression}
|
\subsubsection{Index compression}
|
||||||
|
|
||||||
A limitation in data structures that have
|
A limitation in data structures that
|
||||||
been built upon an array is that
|
are built upon an array is that
|
||||||
the elements are indexed using integers
|
the elements are indexed using integers
|
||||||
$1,2,3,$ etc.
|
$1,2,3,$ etc.
|
||||||
Difficulties arise when the indices
|
Difficulties arise when large indices
|
||||||
needed are large.
|
are needed.
|
||||||
For example, using the index $10^9$ would
|
For example, if we wish to use the index $10^9$,
|
||||||
require that the array would contain $10^9$
|
the array should contain $10^9$
|
||||||
elements which is not realistic.
|
elements which is not realistic.
|
||||||
|
|
||||||
\index{index compression}
|
\index{index compression}
|
||||||
|
|
||||||
However, we can often bypass this limitation
|
However, we can often bypass this limitation
|
||||||
by using \key{index compression}
|
by using \key{index compression},
|
||||||
where the indices are redistributed so that
|
where the original indices are replaced
|
||||||
they are integers $1,2,3,$ etc.
|
with the indices $1,2,3,$ etc.
|
||||||
This can be done if we know all the indices
|
This can be done if we know all the indices
|
||||||
needed during the algorithm beforehand.
|
needed during the algorithm beforehand.
|
||||||
|
|
||||||
The idea is to replace each original index $x$
|
The idea is to replace each original index $x$
|
||||||
with index $p(x)$ where $p$ is a function that
|
with $p(x)$ where $p$ is a function that
|
||||||
redistributes the indices.
|
compresses the indices.
|
||||||
We require that the order of the indices
|
We require that the order of the indices
|
||||||
doesn't change, so if $a<b$, then $p(a)<p(b)$.
|
does not change, so if $a<b$, then $p(a)<p(b)$.
|
||||||
Thanks to this, we can conviently perform queries
|
This allows us to conviently perform queries
|
||||||
despite the fact that the indices are compressed.
|
despite the fact that the indices are compressed.
|
||||||
|
|
||||||
For example, if the original indices are
|
For example, if the original indices are
|
||||||
|
@ -1295,15 +1294,15 @@ p(10^9) & = & 3 \\
|
||||||
So far, we have implemented data structures
|
So far, we have implemented data structures
|
||||||
that support range queries and modifications
|
that support range queries and modifications
|
||||||
of single values.
|
of single values.
|
||||||
Let us now consider a reverse situation
|
Let us now consider a reverse situation,
|
||||||
where we should update ranges and
|
where we should update ranges and
|
||||||
retrieve single values.
|
retrieve single values.
|
||||||
We focus on an operation that increases all
|
We focus on an operation that increases all
|
||||||
elements in range $[a,b]$ by $x$.
|
elements in a range $[a,b]$ by $x$.
|
||||||
|
|
||||||
Surprisingly, we can use the data structures
|
Surprisingly, we can use the data structures
|
||||||
presented in this chapter also in this situation.
|
presented in this chapter also in this situation.
|
||||||
This requires that we change the array so that
|
To do this, we change the array so that
|
||||||
each element indicates the \emph{change}
|
each element indicates the \emph{change}
|
||||||
with respect to the previous element.
|
with respect to the previous element.
|
||||||
For example, the array
|
For example, the array
|
||||||
|
@ -1361,18 +1360,18 @@ becomes as follows:
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
The original array is the sum array of the new array.
|
The original array is the sum array of the new array.
|
||||||
Thus, any value in the original array corresponds
|
Thus, each element in the original array equals
|
||||||
to a sum of elements in the new array.
|
a sum of values in the new array.
|
||||||
For example, the value 6 at index 5 in the original array
|
For example, the value 5 at position 6 in the original array
|
||||||
corresponds to the sum $3-2+4=5$.
|
corresponds to the sum $3-2+4=5$.
|
||||||
|
|
||||||
The benefit in using the new array is
|
The benefit in using the new array is
|
||||||
that we can update a range by changing just
|
that we can update a range by changing just
|
||||||
two elements in the new array.
|
two elements in the array.
|
||||||
For example, if we want to
|
For example, if we want to
|
||||||
increase the range $2 \ldots 5$ by 5,
|
increase the elements in the range $2 \ldots 5$ by 5,
|
||||||
it suffices to increase the element at index 2 by 5
|
it suffices to increase the value at position 2 by 5
|
||||||
and decrease the element at index 6 by 5.
|
and decrease the value at position 6 by 5.
|
||||||
The result is as follows:
|
The result is as follows:
|
||||||
|
|
||||||
\begin{center}
|
\begin{center}
|
||||||
|
@ -1400,18 +1399,17 @@ The result is as follows:
|
||||||
\end{tikzpicture}
|
\end{tikzpicture}
|
||||||
\end{center}
|
\end{center}
|
||||||
|
|
||||||
More generally, to increase the range
|
More generally, to increase the elements
|
||||||
$a \ldots b$ by $x$,
|
in the range $[a,b]$ by $x$,
|
||||||
we increase the element at index $a$ by $x$
|
we increase the value at position $a$ by $x$
|
||||||
and decrease the element at index $b+1$ by $x$.
|
and decrease the value at position $b+1$ by $x$.
|
||||||
The required operations are calculating
|
Thus, it is only needed to update single values
|
||||||
the sum in a range and updating a value,
|
and process sum queries,
|
||||||
so we can use a binary indexed tree or a segment tree.
|
so we can use a binary indexed tree or a segment tree.
|
||||||
|
|
||||||
A more difficult problem is to support both
|
A more difficult problem is to support both
|
||||||
range queries and range updates.
|
range queries and range updates.
|
||||||
In Chapter 28 we will see that this is possible
|
In Chapter 28 we will see that even this is possible.
|
||||||
as well.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue