Small fixes
This commit is contained in:
		
							parent
							
								
									d4ea994907
								
							
						
					
					
						commit
						797035fd8a
					
				|  | @ -759,7 +759,7 @@ up to an integer. For example, | ||||||
| 
 | 
 | ||||||
| The functions $\min(x_1,x_2,\ldots,x_n)$ | The functions $\min(x_1,x_2,\ldots,x_n)$ | ||||||
| and $\max(x_1,x_2,\ldots,x_n)$ | and $\max(x_1,x_2,\ldots,x_n)$ | ||||||
| return the smallest and largest of values | give the smallest and largest of values | ||||||
| $x_1,x_2,\ldots,x_n$. | $x_1,x_2,\ldots,x_n$. | ||||||
| For example, | For example, | ||||||
| \[ \min(1,2,3)=1 \hspace{10px} \textrm{and} \hspace{10px} \max(1,2,3)=3.\] | \[ \min(1,2,3)=1 \hspace{10px} \textrm{and} \hspace{10px} \max(1,2,3)=3.\] | ||||||
|  | @ -793,7 +793,7 @@ There is also a closed-form formula | ||||||
| for calculating Fibonacci numbers: | for calculating Fibonacci numbers: | ||||||
| \[f(n)=\frac{(1 + \sqrt{5})^n - (1-\sqrt{5})^n}{2^n \sqrt{5}}.\] | \[f(n)=\frac{(1 + \sqrt{5})^n - (1-\sqrt{5})^n}{2^n \sqrt{5}}.\] | ||||||
| 
 | 
 | ||||||
| \subsubsection{Logarithm} | \subsubsection{Logarithms} | ||||||
| 
 | 
 | ||||||
| \index{logarithm} | \index{logarithm} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										16
									
								
								luku04.tex
								
								
								
								
							
							
						
						
									
										16
									
								
								luku04.tex
								
								
								
								
							|  | @ -20,7 +20,7 @@ Later in the book we will learn more sophisticated | ||||||
| data structures that are not available | data structures that are not available | ||||||
| in the standard library. | in the standard library. | ||||||
| 
 | 
 | ||||||
| \section{Dynamic array} | \section{Dynamic arrays} | ||||||
| 
 | 
 | ||||||
| \index{dynamic array} | \index{dynamic array} | ||||||
| \index{vector} | \index{vector} | ||||||
|  | @ -135,7 +135,7 @@ string c = b.substr(3,4); | ||||||
| cout << c << "\n"; // tiva | cout << c << "\n"; // tiva | ||||||
| \end{lstlisting} | \end{lstlisting} | ||||||
| 
 | 
 | ||||||
| \section{Set structure} | \section{Set structures} | ||||||
| 
 | 
 | ||||||
| \index{set} | \index{set} | ||||||
| 
 | 
 | ||||||
|  | @ -243,7 +243,7 @@ s.erase(s.find(5)); | ||||||
| cout << s.count(5) << "\n"; // 2 | cout << s.count(5) << "\n"; // 2 | ||||||
| \end{lstlisting} | \end{lstlisting} | ||||||
| 
 | 
 | ||||||
| \section{Map structure} | \section{Map structures} | ||||||
| 
 | 
 | ||||||
| \index{map} | \index{map} | ||||||
| 
 | 
 | ||||||
|  | @ -469,7 +469,7 @@ element that corresponds to $a$ or the previous element. | ||||||
| 
 | 
 | ||||||
| \section{Other structures} | \section{Other structures} | ||||||
| 
 | 
 | ||||||
| \subsubsection{Bitset} | \subsubsection{Bitsets} | ||||||
| 
 | 
 | ||||||
| \index{bitset} | \index{bitset} | ||||||
| 
 | 
 | ||||||
|  | @ -524,7 +524,7 @@ cout << (a|b) << "\n"; // 1011111110 | ||||||
| cout << (a^b) << "\n"; // 1001101110 | cout << (a^b) << "\n"; // 1001101110 | ||||||
| \end{lstlisting} | \end{lstlisting} | ||||||
| 
 | 
 | ||||||
| \subsubsection{Deque} | \subsubsection{Deques} | ||||||
| 
 | 
 | ||||||
| \index{deque} | \index{deque} | ||||||
| 
 | 
 | ||||||
|  | @ -552,7 +552,7 @@ For this reason, a deque is slower than a vector. | ||||||
| Still, the time complexity of adding and removing | Still, the time complexity of adding and removing | ||||||
| elements is $O(1)$ on average at both ends. | elements is $O(1)$ on average at both ends. | ||||||
| 
 | 
 | ||||||
| \subsubsection{Stack} | \subsubsection{Stacks} | ||||||
| 
 | 
 | ||||||
| \index{stack} | \index{stack} | ||||||
| 
 | 
 | ||||||
|  | @ -574,7 +574,7 @@ cout << s.top(); // 5 | ||||||
| s.pop(); | s.pop(); | ||||||
| cout << s.top(); // 2 | cout << s.top(); // 2 | ||||||
| \end{lstlisting} | \end{lstlisting} | ||||||
| \subsubsection{Queue} | \subsubsection{Queues} | ||||||
| 
 | 
 | ||||||
| \index{queue} | \index{queue} | ||||||
| 
 | 
 | ||||||
|  | @ -596,7 +596,7 @@ s.pop(); | ||||||
| cout << s.front(); // 2 | cout << s.front(); // 2 | ||||||
| \end{lstlisting} | \end{lstlisting} | ||||||
| 
 | 
 | ||||||
| \subsubsection{Priority queue} | \subsubsection{Priority queues} | ||||||
| 
 | 
 | ||||||
| \index{priority queue} | \index{priority queue} | ||||||
| \index{heap} | \index{heap} | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								luku07.tex
								
								
								
								
							
							
						
						
									
										10
									
								
								luku07.tex
								
								
								
								
							|  | @ -119,7 +119,7 @@ we should form the sum $x-3$ or $x-4$. | ||||||
| 
 | 
 | ||||||
| Thus, the recursive formula is | Thus, the recursive formula is | ||||||
| \[f(x) = \min(f(x-1),f(x-3),f(x-4))+1\] | \[f(x) = \min(f(x-1),f(x-3),f(x-4))+1\] | ||||||
| where the function $\min$ returns the smallest | where the function $\min$ gives the smallest | ||||||
| of its parameters. | of its parameters. | ||||||
| In the general case, for the coin set | In the general case, for the coin set | ||||||
| $\{c_1,c_2,\ldots,c_k\}$, | $\{c_1,c_2,\ldots,c_k\}$, | ||||||
|  | @ -250,7 +250,7 @@ that are implemented using loops. | ||||||
| Still, the underlying idea is the same as | Still, the underlying idea is the same as | ||||||
| in the recursive function. | in the recursive function. | ||||||
| 
 | 
 | ||||||
| \subsubsection{Constructing the solution} | \subsubsection{Constructing a solution} | ||||||
| 
 | 
 | ||||||
| Sometimes we are asked both to find the value | Sometimes we are asked both to find the value | ||||||
| of an optimal solution and also to give | of an optimal solution and also to give | ||||||
|  | @ -319,7 +319,7 @@ we maximize or minimize something in the recursion, | ||||||
| but now we will calculate sums of numbers of solutions. | but now we will calculate sums of numbers of solutions. | ||||||
| 
 | 
 | ||||||
| To solve the problem, we can define a function $f(x)$ | To solve the problem, we can define a function $f(x)$ | ||||||
| that returns the number of ways to construct | that gives the number of ways to construct | ||||||
| the sum $x$ using the coins. | the sum $x$ using the coins. | ||||||
| For example, $f(5)=6$ when the coins are $\{1,3,4\}$. | For example, $f(5)=6$ when the coins are $\{1,3,4\}$. | ||||||
| The value of $f(x)$ can be calculated recursively | The value of $f(x)$ can be calculated recursively | ||||||
|  | @ -505,9 +505,9 @@ go through all previous values | ||||||
| $f(1),f(2),\ldots,f(k-1)$ and select the best solution. | $f(1),f(2),\ldots,f(k-1)$ and select the best solution. | ||||||
| The time complexity of such an algorithm is $O(n^2)$. | The time complexity of such an algorithm is $O(n^2)$. | ||||||
| Surprisingly, it is also possible to solve the | Surprisingly, it is also possible to solve the | ||||||
| problem in $O(n \log n)$ time, but this is more difficult. | problem in $O(n \log n)$ time. Can you see how? | ||||||
| 
 | 
 | ||||||
| \section{Path in a grid} | \section{Paths in a grid} | ||||||
| 
 | 
 | ||||||
| Our next problem is to find a path | Our next problem is to find a path | ||||||
| in an $n \times n$ grid | in an $n \times n$ grid | ||||||
|  |  | ||||||
							
								
								
									
										12
									
								
								luku08.tex
								
								
								
								
							
							
						
						
									
										12
									
								
								luku08.tex
								
								
								
								
							|  | @ -245,13 +245,13 @@ Since both the left and right pointer | ||||||
| move $O(n)$ steps during the algorithm, | move $O(n)$ steps during the algorithm, | ||||||
| the time complexity is $O(n)$. | the time complexity is $O(n)$. | ||||||
| 
 | 
 | ||||||
| \subsubsection{2SUM-problem} | \subsubsection{2SUM problem} | ||||||
| 
 | 
 | ||||||
| \index{2SUM-problem} | \index{2SUM problem} | ||||||
| 
 | 
 | ||||||
| Another problem that can be solved using | Another problem that can be solved using | ||||||
| the two pointers method is the following problem, | the two pointers method is the following problem, | ||||||
| also known as the \key{2SUM-problem}: | also known as the \key{2SUM problem}: | ||||||
| We are given an array of $n$ numbers and | We are given an array of $n$ numbers and | ||||||
| a target sum $x$, and our task is to find two numbers | a target sum $x$, and our task is to find two numbers | ||||||
| in the array such that their sum is $x$, | in the array such that their sum is $x$, | ||||||
|  | @ -414,13 +414,13 @@ number such that the sum is $x$. | ||||||
| This can be done by performing $n$ binary searches, | This can be done by performing $n$ binary searches, | ||||||
| and each search takes $O(\log n)$ time. | and each search takes $O(\log n)$ time. | ||||||
| 
 | 
 | ||||||
| \index{3SUM-problem} | \index{3SUM problem} | ||||||
| A more difficult problem is  | A more difficult problem is  | ||||||
| the \key{3SUM-problem} that asks to | the \key{3SUM problem} that asks to | ||||||
| find \emph{three} numbers in the array | find \emph{three} numbers in the array | ||||||
| such that their sum is $x$. | such that their sum is $x$. | ||||||
| This problem can be solved in $O(n^2)$ time. | This problem can be solved in $O(n^2)$ time. | ||||||
| Can you see how it is possible? | Can you see how? | ||||||
| 
 | 
 | ||||||
| \section{Nearest smaller elements} | \section{Nearest smaller elements} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										14
									
								
								luku09.tex
								
								
								
								
							
							
						
						
									
										14
									
								
								luku09.tex
								
								
								
								
							|  | @ -432,7 +432,7 @@ the union of the ranges $[2,5]$ and $[4,7]$: | ||||||
| Since $\textrm{rmq}(2,5)=3$ and $\textrm{rmq}(4,7)=1$, | Since $\textrm{rmq}(2,5)=3$ and $\textrm{rmq}(4,7)=1$, | ||||||
| we can conclude that $\textrm{rmq}(2,7)=1$. | we can conclude that $\textrm{rmq}(2,7)=1$. | ||||||
| 
 | 
 | ||||||
| \section{Binary indexed tree} | \section{Binary indexed trees} | ||||||
| 
 | 
 | ||||||
| \index{binary indexed tree} | \index{binary indexed tree} | ||||||
| \index{Fenwick tree} | \index{Fenwick tree} | ||||||
|  | @ -567,7 +567,7 @@ corresponds to a range in the array: | ||||||
| \end{tikzpicture} | \end{tikzpicture} | ||||||
| \end{center} | \end{center} | ||||||
| 
 | 
 | ||||||
| \subsubsection{Sum query} | \subsubsection{Sum queries} | ||||||
| 
 | 
 | ||||||
| The values in the binary indexed tree | The values in the binary indexed tree | ||||||
| can be used to efficiently calculate | can be used to efficiently calculate | ||||||
|  | @ -629,7 +629,7 @@ we can use the same trick that we used with sum arrays: | ||||||
| \[ \textrm{sum}(a,b) = \textrm{sum}(1,b) - \textrm{sum}(1,a-1).\] | \[ \textrm{sum}(a,b) = \textrm{sum}(1,b) - \textrm{sum}(1,a-1).\] | ||||||
| Also in this case, only $O(\log n)$ values are needed. | Also in this case, only $O(\log n)$ values are needed. | ||||||
| 
 | 
 | ||||||
| \subsubsection{Array update} | \subsubsection{Array updates} | ||||||
| 
 | 
 | ||||||
| When a value in the array changes, | When a value in the array changes, | ||||||
| several values in the binary indexed tree should be updated. | several values in the binary indexed tree should be updated. | ||||||
|  | @ -731,7 +731,7 @@ values in the binary indexed tree, and each move | ||||||
| to the next position | to the next position | ||||||
| takes $O(1)$ time using bit operations. | takes $O(1)$ time using bit operations. | ||||||
| 
 | 
 | ||||||
| \section{Segment tree} | \section{Segment trees} | ||||||
| 
 | 
 | ||||||
| \index{segment tree} | \index{segment tree} | ||||||
| 
 | 
 | ||||||
|  | @ -841,7 +841,7 @@ node is the sum of the corresponding array elements, | ||||||
| and it can be calculated as the sum of | 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. | ||||||
| 
 | 
 | ||||||
| \subsubsection{Range query} | \subsubsection{Range queries} | ||||||
| 
 | 
 | ||||||
| The sum of elements in a given range | The sum of elements in a given range | ||||||
| can be calculated as a sum of values in the segment tree. | can be calculated as a sum of values in the segment tree. | ||||||
|  | @ -922,7 +922,7 @@ of the tree are needed. | ||||||
| Hence, the total number of nodes | Hence, the total number of nodes | ||||||
| is only $O(\log n)$. | is only $O(\log n)$. | ||||||
| 
 | 
 | ||||||
| \subsubsection{Array update} | \subsubsection{Array updates} | ||||||
| 
 | 
 | ||||||
| When an element in the array changes, | When an element in the array changes, | ||||||
| we should update all nodes in the tree | we should update all nodes in the tree | ||||||
|  | @ -1200,7 +1200,7 @@ element in the whole array. | ||||||
| The operations 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 a tree} | ||||||
| 
 | 
 | ||||||
| The structure of the segment tree allows us | The structure of the segment tree allows us | ||||||
| to use binary search for finding elements in the array. | to use binary search for finding elements in the array. | ||||||
|  |  | ||||||
|  | @ -492,7 +492,7 @@ The reason for this is that any successor graph | ||||||
| corresponds to a function $f$ that defines | corresponds to a function $f$ that defines | ||||||
| the edges in the graph. | the edges in the graph. | ||||||
| The parameter for the function is a node in the graph, | The parameter for the function is a node in the graph, | ||||||
| and the function returns the successor of the node. | and the function gives the successor of the node. | ||||||
| 
 | 
 | ||||||
| \begin{samepage} | \begin{samepage} | ||||||
| For example, the function | For example, the function | ||||||
|  |  | ||||||
|  | @ -18,7 +18,7 @@ find a such path if it exists. | ||||||
| On the contrary, checking the existence of a Hamiltonian path is a NP-hard | On the contrary, checking the existence of a Hamiltonian path is a NP-hard | ||||||
| problem and no efficient algorithm is known for solving the problem. | problem and no efficient algorithm is known for solving the problem. | ||||||
| 
 | 
 | ||||||
| \section{Eulerian path} | \section{Eulerian paths} | ||||||
| 
 | 
 | ||||||
| \index{Eulerian path} | \index{Eulerian path} | ||||||
| 
 | 
 | ||||||
|  | @ -391,7 +391,7 @@ to the circuit: | ||||||
| Now all edges are included in the circuit, | Now all edges are included in the circuit, | ||||||
| so we have successfully constructed an Eulerian circuit. | so we have successfully constructed an Eulerian circuit. | ||||||
| 
 | 
 | ||||||
| \section{Hamiltonian path} | \section{Hamiltonian paths} | ||||||
| 
 | 
 | ||||||
| \index{Hamiltonian path} | \index{Hamiltonian path} | ||||||
| 
 | 
 | ||||||
|  | @ -521,7 +521,7 @@ The function indicates whether there is a Hamiltonian path | ||||||
| that visits the nodes in $s$ and ends at node $x$. | that visits the nodes in $s$ and ends at node $x$. | ||||||
| It is possible to implement this solution in $O(2^n n^2)$ time. | It is possible to implement this solution in $O(2^n n^2)$ time. | ||||||
| 
 | 
 | ||||||
| \section{De Bruijn sequence} | \section{De Bruijn sequences} | ||||||
| 
 | 
 | ||||||
| \index{De Bruijn sequence} | \index{De Bruijn sequence} | ||||||
| 
 | 
 | ||||||
|  | @ -573,7 +573,7 @@ The starting node has $n-1$ characters | ||||||
| and there are $k^n$ characters in the edges, | and there are $k^n$ characters in the edges, | ||||||
| so the length of the string is $k^n+n-1$. | so the length of the string is $k^n+n-1$. | ||||||
| 
 | 
 | ||||||
| \section{Knight's tour} | \section{Knight's tours} | ||||||
| 
 | 
 | ||||||
| \index{knight's tour} | \index{knight's tour} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -89,7 +89,7 @@ It is easy see that this flow is maximum, | ||||||
| because the total capacity of the edges | because the total capacity of the edges | ||||||
| leading to the sink is $7$. | leading to the sink is $7$. | ||||||
| 
 | 
 | ||||||
| \subsubsection{Minimum cut} | \subsubsection{Minimum cuts} | ||||||
| 
 | 
 | ||||||
| \index{cut} | \index{cut} | ||||||
| \index{minimum cut} | \index{minimum cut} | ||||||
|  |  | ||||||
|  | @ -323,7 +323,7 @@ There are $k+1$ positions, | ||||||
| so the number of solutions is | so the number of solutions is | ||||||
| ${n-2k+1+k+1-1 \choose n-2k+1} = {n-k+1 \choose n-2k+1}$. | ${n-2k+1+k+1-1 \choose n-2k+1} = {n-k+1 \choose n-2k+1}$. | ||||||
| 
 | 
 | ||||||
| \subsubsection{Multinomial coefficient} | \subsubsection{Multinomial coefficients} | ||||||
| 
 | 
 | ||||||
| \index{multinomial coefficient} | \index{multinomial coefficient} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -386,7 +386,7 @@ sticks in a nim heap. | ||||||
| When we know the Grundy numbers for all states, | When we know the Grundy numbers for all states, | ||||||
| we can play the game like the nim game. | we can play the game like the nim game. | ||||||
| 
 | 
 | ||||||
| \subsubsection{Grundy number} | \subsubsection{Grundy numbers} | ||||||
| 
 | 
 | ||||||
| \index{Grundy number} | \index{Grundy number} | ||||||
| \index{mex function} | \index{mex function} | ||||||
|  |  | ||||||
|  | @ -108,7 +108,7 @@ It means that $x<y$ if either $x \neq y$ and $x$ is a prefix of $y$, | ||||||
| or there is a position $k$ such that | or there is a position $k$ such that | ||||||
| $x[i]=y[i]$ when $i<k$ and $x[k]<y[k]$. | $x[i]=y[i]$ when $i<k$ and $x[k]<y[k]$. | ||||||
| 
 | 
 | ||||||
| \section{Trie structure} | \section{Trie structures} | ||||||
| 
 | 
 | ||||||
| \index{trie} | \index{trie} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -199,7 +199,7 @@ Both operations can be implemented using | ||||||
| similar ideas, and it is even possible to construct | similar ideas, and it is even possible to construct | ||||||
| a tree that supports both operations at the same time. | a tree that supports both operations at the same time. | ||||||
| 
 | 
 | ||||||
| \subsubsection{Lazy segment tree} | \subsubsection{Lazy segment trees} | ||||||
| 
 | 
 | ||||||
| Let us consider an example where our goal is to | Let us consider an example where our goal is to | ||||||
| construct a segment tree that supports | construct a segment tree that supports | ||||||
|  | @ -506,7 +506,7 @@ In this problem, it is easy to combine lazy updates, | ||||||
| because the combination of updates $z_1$ and $z_2$ | because the combination of updates $z_1$ and $z_2$ | ||||||
| corresponds to an update $z_1+z_2$. | corresponds to an update $z_1+z_2$. | ||||||
| 
 | 
 | ||||||
| \subsubsection{Polynomial update} | \subsubsection{Polynomial updates} | ||||||
| 
 | 
 | ||||||
| Lazy updates can be generalized so that it is | Lazy updates can be generalized so that it is | ||||||
| possible to update ranges using polynomials of the form | possible to update ranges using polynomials of the form | ||||||
|  | @ -584,7 +584,7 @@ node *u = new node(0, 0, 15); | ||||||
| u->s = 5; | u->s = 5; | ||||||
| \end{lstlisting} | \end{lstlisting} | ||||||
| 
 | 
 | ||||||
| \subsubsection{Sparse segment tree} | \subsubsection{Sparse segment trees} | ||||||
| 
 | 
 | ||||||
| \index{sparse segment tree} | \index{sparse segment tree} | ||||||
| 
 | 
 | ||||||
|  | @ -645,7 +645,7 @@ index compression (Chapter 9.4). | ||||||
| However, this is not possible if the indices | However, this is not possible if the indices | ||||||
| are generated during the algorithm. | are generated during the algorithm. | ||||||
| 
 | 
 | ||||||
| \subsubsection{Persistent segment tree} | \subsubsection{Persistent segment trees} | ||||||
| 
 | 
 | ||||||
| \index{persistent segment tree} | \index{persistent segment tree} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -527,7 +527,7 @@ For example, the area of the polygon | ||||||
| \end{tikzpicture} | \end{tikzpicture} | ||||||
| \end{center} | \end{center} | ||||||
| is | is | ||||||
| \[\frac{|(2\cdot5-4\cdot5)+(5\cdot3-5\cdot7)+(7\cdot1-3\cdot4)+(4\cdot3-1\cdot4)+(4\cdot4-3\cdot2)|}{2} = 17/2.\] | \[\frac{|(2\cdot5-5\cdot4)+(5\cdot3-7\cdot5)+(7\cdot1-4\cdot3)+(4\cdot3-4\cdot1)+(4\cdot4-2\cdot3)|}{2} = 17/2.\] | ||||||
| 
 | 
 | ||||||
| The idea in the formula is to go through trapezoids | The idea in the formula is to go through trapezoids | ||||||
| whose one side is a side of the polygon, | whose one side is a side of the polygon, | ||||||
|  | @ -565,7 +565,7 @@ all such trapezoids, which yields the formula | ||||||
| Note that the absolute value of the sum is taken, | Note that the absolute value of the sum is taken, | ||||||
| because the value of the sum may be positive or negative | because the value of the sum may be positive or negative | ||||||
| depending on whether we walk clockwise or counterclockwise | depending on whether we walk clockwise or counterclockwise | ||||||
| along the perimeter of the polygon. | along the boundary of the polygon. | ||||||
| 
 | 
 | ||||||
| \subsubsection{Pick's theorem} | \subsubsection{Pick's theorem} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue