Corrections

This commit is contained in:
Antti H S Laaksonen 2017-01-30 20:39:11 +02:00
parent 61afed2a17
commit 5573a59348
2 changed files with 78 additions and 76 deletions

View File

@ -4,12 +4,12 @@
The purpose of this book is to give you The purpose of this book is to give you
a thorough introduction to competitive programming. a thorough introduction to competitive programming.
The book assumes that you already It is assumed that you already
know the basics of programming, but previous know the basics of programming, but previous
background on competitive programming is not needed. background on competitive programming is not needed.
The book is especially intended for The book is especially intended for
high school students who want to learn secondary school students who want to learn
algorithms and possibly participate in algorithms and possibly participate in
the International Olympiad in Informatics (IOI). the International Olympiad in Informatics (IOI).
The book is also suitable for university students The book is also suitable for university students
@ -19,7 +19,7 @@ It takes a long time to become a good competitive
programmer, but it is also an opportunity to learn a lot. programmer, but it is also an opportunity to learn a lot.
You can be sure that you will learn a great deal You can be sure that you will learn a great deal
about algorithms if you spend time reading the book about algorithms if you spend time reading the book
and solving exercises. and solving problems.
The book is under continuous development. The book is under continuous development.
You can always send feedback about the book to You can always send feedback about the book to

View File

@ -1,12 +1,12 @@
\chapter{Introduction} \chapter{Introduction}
Competitive programming combines two topics: Competitive programming combines two topics:
(1) design of algorithms and (2) implementation of algorithms. (1) the design of algorithms and (2) the implementation of algorithms.
The \key{design of algorithms} consists of problem solving The \key{design of algorithms} consists of problem solving
and mathematical thinking. and mathematical thinking.
Skills for analyzing problems and solving them Skills for analyzing problems and solving them
using creativity is needed. creatively is needed.
An algorithm for solving a problem An algorithm for solving a problem
has to be both correct and efficient, has to be both correct and efficient,
and the core of the problem is often and the core of the problem is often
@ -63,23 +63,24 @@ large collection
of data structures and algorithms. of data structures and algorithms.
On the other hand, it is good to On the other hand, it is good to
master several languages and know the master several languages and know
benefits of them. their strengths.
For example, if big integers are needed For example, if large numbers are needed
in the problem, in the problem,
Python can be a good choice because it Python can be a good choice because it
contains a built-in library for handling contains a built-in library for handling
big integers. large numbers.
Still, usually the goal is to write the problems so that Still, most problems in programming contests
the use of a specific programming language are set so that
is not an unfair advantage in the contest. using a specific programming language
is not an unfair advantage.
All examples in this book are written in C++, All example programs in this book are written in C++,
and the data structures and algorithms in and the standard library's
the standard library are often used. data structures and algorithms are often used.
The book follows the C++11 standard, The programs follow the C++11 standard,
that can be used in most contests nowadays. that can be used in most contests nowadays.
If you can't program in C++ yet, If you cannot program in C++ yet,
now it is a good time to start learning. now it is a good time to start learning.
\subsubsection{C++ template} \subsubsection{C++ template}
@ -155,21 +156,21 @@ or one newline between each element in the input.
For example, the above code accepts For example, the above code accepts
both the following inputs: both the following inputs:
\begin{lstlisting} \begin{lstlisting}
123 456 apina 123 456 monkey
\end{lstlisting} \end{lstlisting}
\begin{lstlisting} \begin{lstlisting}
123 456 123 456
apina monkey
\end{lstlisting} \end{lstlisting}
The \texttt{cout} stream is used for output The \texttt{cout} stream is used for output
as follows: as follows:
\begin{lstlisting} \begin{lstlisting}
int a = 123, b = 456; int a = 123, b = 456;
string x = "apina"; string x = "monkey";
cout << a << " " << b << " " << x << "\n"; cout << a << " " << b << " " << x << "\n";
\end{lstlisting} \end{lstlisting}
Handling input and output is sometimes Input and output is sometimes
a bottleneck in the program. a bottleneck in the program.
The following lines at the beginning of the code The following lines at the beginning of the code
make input and output more efficient: make input and output more efficient:
@ -181,7 +182,7 @@ cin.tie(0);
Note that the newline \texttt{"\textbackslash n"} Note that the newline \texttt{"\textbackslash n"}
works faster than \texttt{endl}, works faster than \texttt{endl},
becauses \texttt{endl} always causes because \texttt{endl} always causes
a flush operation. a flush operation.
The C functions \texttt{scanf} The C functions \texttt{scanf}
@ -214,7 +215,7 @@ If the amount of data is unknown, the following
loop can be handy: loop can be handy:
\begin{lstlisting} \begin{lstlisting}
while (cin >> x) { while (cin >> x) {
// koodia // code
} }
\end{lstlisting} \end{lstlisting}
This loop reads elements from the input This loop reads elements from the input
@ -240,14 +241,14 @@ After this, the code reads the input from the file
\subsubsection{Integers} \subsubsection{Integers}
The most popular integer type in competitive programming The most used integer type in competitive programming
is \texttt{int}. This is a 32-bit type with is \texttt{int}, that is a 32-bit type with
value range $-2^{31} \ldots 2^{31}-1$, value range $-2^{31} \ldots 2^{31}-1$
i.e., about $-2 \cdot 10^9 \ldots 2 \cdot 10^9$. or about $-2 \cdot 10^9 \ldots 2 \cdot 10^9$.
If the type \texttt{int} is not enough, If the type \texttt{int} is not enough,
the 64-bit type \texttt{long long} can be used, the 64-bit type \texttt{long long} can be used,
with value range $-2^{63} \ldots 2^{63}-1$, with value range $-2^{63} \ldots 2^{63}-1$
i.e., about $-9 \cdot 10^{18} \ldots 9 \cdot 10^{18}$. or about $-9 \cdot 10^{18} \ldots 9 \cdot 10^{18}$.
The following code defines a The following code defines a
\texttt{long long} variable: \texttt{long long} variable:
@ -257,7 +258,7 @@ long long x = 123456789123456789LL;
The suffix \texttt{LL} means that the The suffix \texttt{LL} means that the
type of the number is \texttt{long long}. type of the number is \texttt{long long}.
A typical error when using the type \texttt{long long} A common error when using the type \texttt{long long}
is that the type \texttt{int} is still used somewhere is that the type \texttt{int} is still used somewhere
in the code. in the code.
For example, the following code contains For example, the following code contains
@ -279,13 +280,13 @@ The problem can be solved by changing the type
of \texttt{a} to \texttt{long long} or of \texttt{a} to \texttt{long long} or
by changing the expression to \texttt{(long long)a*a}. by changing the expression to \texttt{(long long)a*a}.
Usually, the problems are written so that the Usually contest problems are set so that the
type \texttt{long long} is enough. type \texttt{long long} is enough.
Still, it is good to know that Still, it is good to know that
the \texttt{g++} compiler also features the \texttt{g++} compiler also provides
an 128-bit type \texttt{\_\_int128\_t} an 128-bit type \texttt{\_\_int128\_t}
with value range with value range
$-2^{127} \ldots 2^{127}-1$, i.e., $-10^{38} \ldots 10^{38}$. $-2^{127} \ldots 2^{127}-1$ or $-10^{38} \ldots 10^{38}$.
However, this type is not available in all contest systems. However, this type is not available in all contest systems.
\subsubsection{Modular arithmetic} \subsubsection{Modular arithmetic}
@ -299,12 +300,12 @@ For example, $17 \bmod 5 = 2$,
because $17 = 3 \cdot 5 + 2$. because $17 = 3 \cdot 5 + 2$.
Sometimes, the answer for a problem is a Sometimes, the answer for a problem is a
very big integer but it is enough to very large number but it is enough to
print it ''modulo $m$'', i.e., output it ''modulo $m$'', i.e.,
the remainder when the answer is divided by $m$ the remainder when the answer is divided by $m$
(for example, ''modulo $10^9+7$''). (for example, ''modulo $10^9+7$'').
The idea is that even if the actual answer The idea is that even if the actual answer
may be very big, may be very large,
it is enough to use the types it is enough to use the types
\texttt{int} and \texttt{long long}. \texttt{int} and \texttt{long long}.
@ -333,12 +334,12 @@ for (int i = 2; i <= n i++) {
cout << x << "\n"; cout << x << "\n";
\end{lstlisting} \end{lstlisting}
Usually, the answer should be always given so Usually the remainder should be always
that the remainder is between $0\ldots m-1$. be between $0\ldots m-1$.
However, in C++ and other languages, However, in C++ and other languages,
the remainder of a negative number can the remainder of a negative number
be negative. is either zero or negative.
An easy way to make sure that this will An easy way to make sure this will
not happen is to first calculate not happen is to first calculate
the remainder as usual and then add $m$ the remainder as usual and then add $m$
if the result is negative: if the result is negative:
@ -363,10 +364,11 @@ In most cases, \texttt{double} is enough,
but \texttt{long double} is more accurate. but \texttt{long double} is more accurate.
The required precision of the answer The required precision of the answer
is usually given. is usually given in the problem statement.
The easiest way is to use An easy way to output the answer is to use
the \texttt{printf} function the \texttt{printf} function
that can be given the number of decimal places. and give the number of decimal places
in the formatting string.
For example, the following code prints For example, the following code prints
the value of $x$ with 9 decimal places: the value of $x$ with 9 decimal places:
@ -376,7 +378,7 @@ printf("%.9f\n", x);
A difficulty when using floating point numbers A difficulty when using floating point numbers
is that some numbers cannot be represented is that some numbers cannot be represented
accurately, but there will be rounding errors. accurately but there will be rounding errors.
For example, the result of the following code For example, the result of the following code
is surprising: is surprising:
@ -417,7 +419,7 @@ integers having absolute value at most $2^{53}$.
\section{Shortening code} \section{Shortening code}
Short code is ideal in competitive programming, Short code is ideal in competitive programming,
because the algorithm should be implemented because algorithms should be implemented
as fast as possible. as fast as possible.
Because of this, competitive programmers often define Because of this, competitive programmers often define
shorter names for datatypes and other parts of code. shorter names for datatypes and other parts of code.
@ -485,9 +487,9 @@ v.PB(MP(y2,x2));
int d = v[i].F+v[i].S; int d = v[i].F+v[i].S;
\end{lstlisting} \end{lstlisting}
It is also possible to define a macro with parameters A macro can also have parameters
which makes it possible to shorten loops and other which makes it possible to shorten loops and other
structures in the code. structures.
For example, we can define the following macro: For example, we can define the following macro:
\begin{lstlisting} \begin{lstlisting}
#define REP(i,a,b) for (int i = a; i <= b; i++) #define REP(i,a,b) for (int i = a; i <= b; i++)
@ -495,13 +497,13 @@ For example, we can define the following macro:
After this, the code After this, the code
\begin{lstlisting} \begin{lstlisting}
for (int i = 1; i <= n; i++) { for (int i = 1; i <= n; i++) {
haku(i); search(i);
} }
\end{lstlisting} \end{lstlisting}
can be shortened as follows: can be shortened as follows:
\begin{lstlisting} \begin{lstlisting}
REP(i,1,n) { REP(i,1,n) {
haku(i); search(i);
} }
\end{lstlisting} \end{lstlisting}
@ -566,7 +568,7 @@ This formula can be derived as follows. Let
By multiplying both sides by $x$, we get By multiplying both sides by $x$, we get
\[ xS = ax + ax^2 + ax^3 + \cdots + bx,\] \[ xS = ax + ax^2 + ax^3 + \cdots + bx,\]
and solving the equation and solving the equation
\[ xS-S = bx-a.\] \[ xS-S = bx-a\]
yields the formula. yields the formula.
A special case of a geometric sum is the formula A special case of a geometric sum is the formula
@ -578,9 +580,9 @@ A \key{harmonic sum} is a sum of the form
\[ \sum_{x=1}^n \frac{1}{x} = 1+\frac{1}{2}+\frac{1}{3}+\ldots+\frac{1}{n}.\] \[ \sum_{x=1}^n \frac{1}{x} = 1+\frac{1}{2}+\frac{1}{3}+\ldots+\frac{1}{n}.\]
An upper bound for the harmonic sum is $\log_2(n)+1$. An upper bound for the harmonic sum is $\log_2(n)+1$.
The reason for this is that we can Namely, we can
change each term $1/k$ so that $k$ becomes modify each term $1/k$ so that $k$ becomes
a power of two that doesn't exceed $k$. the nearest power of two that does not exceed $k$.
For example, when $n=6$, we can estimate For example, when $n=6$, we can estimate
the sum as follows: the sum as follows:
\[ 1+\frac{1}{2}+\frac{1}{3}+\frac{1}{4}+\frac{1}{5}+\frac{1}{6} \le \[ 1+\frac{1}{2}+\frac{1}{3}+\frac{1}{4}+\frac{1}{5}+\frac{1}{6} \le
@ -605,18 +607,18 @@ For example, the set
\[X=\{2,4,7\}\] \[X=\{2,4,7\}\]
contains elements 2, 4 and 7. contains elements 2, 4 and 7.
The symbol $\emptyset$ denotes an empty set, The symbol $\emptyset$ denotes an empty set,
and $|S|$ denotes the size of set $S$, and $|S|$ denotes the size of the set $S$,
i.e., the number of elements in the set. i.e., the number of elements in the set.
For example, in the above set, $|X|=3$. For example, in the above set, $|X|=3$.
If set $S$ contains element $x$, If a set $S$ contains an element $x$,
we write $x \in S$, we write $x \in S$,
and otherwise we write $x \notin S$. and otherwise we write $x \notin S$.
For example, in the above set For example, in the above set
\[4 \in X \hspace{10px}\textrm{and}\hspace{10px} 5 \notin X.\] \[4 \in X \hspace{10px}\textrm{and}\hspace{10px} 5 \notin X.\]
\begin{samepage} \begin{samepage}
New sets can be constructed as follows using set operations: New sets can be constructed using set operations:
\begin{itemize} \begin{itemize}
\item The \key{intersection} $A \cap B$ consists of elements \item The \key{intersection} $A \cap B$ consists of elements
that are both in $A$ and $B$. that are both in $A$ and $B$.
@ -631,7 +633,7 @@ that are not in $A$.
The interpretation of a complement depends on The interpretation of a complement depends on
the \key{universal set} that contains all possible elements. the \key{universal set} that contains all possible elements.
For example, if $A=\{1,2,5,7\}$ and the universal set is For example, if $A=\{1,2,5,7\}$ and the universal set is
$P=\{1,2,\ldots,10\}$, then $\bar A = \{3,4,6,8,9,10\}$. $\{1,2,\ldots,10\}$, then $\bar A = \{3,4,6,8,9,10\}$.
\item The \key{difference} $A \setminus B = A \cap \bar B$ \item The \key{difference} $A \setminus B = A \cap \bar B$
consists of elements that are in $A$ but not in $B$. consists of elements that are in $A$ but not in $B$.
Note that $B$ can contain elements that are not in $A$. Note that $B$ can contain elements that are not in $A$.
@ -643,12 +645,12 @@ then $A \setminus B = \{2,7\}$.
If each element of $A$ also belongs to $S$, If each element of $A$ also belongs to $S$,
we say that $A$ is a \key{subset} of $S$, we say that $A$ is a \key{subset} of $S$,
denoted by $A \subset S$. denoted by $A \subset S$.
Set $S$ always has $2^{|S|}$ subsets, A set $S$ always has $2^{|S|}$ subsets,
including the empty set. including the empty set.
For example, the subsets of the set $\{2,4,7\}$ are For example, the subsets of the set $\{2,4,7\}$ are
\begin{center} \begin{center}
$\emptyset$, $\emptyset$,
$\{2\}$, $\{4\}$, $\{7\}$, $\{2,4\}$, $\{2,7\}$, $\{4,7\}$ ja $\{2,4,7\}$. $\{2\}$, $\{4\}$, $\{7\}$, $\{2,4\}$, $\{2,7\}$, $\{4,7\}$ and $\{2,4,7\}$.
\end{center} \end{center}
Often used sets are Often used sets are
@ -669,7 +671,7 @@ or $\mathbb{N}=\{1,2,3,...\}$.
We can also construct a set using a rule of the form We can also construct a set using a rule of the form
\[\{f(n) : n \in S\},\] \[\{f(n) : n \in S\},\]
where $f(n)$ is some function. where $f(n)$ is some function.
This set contains all elements $f(n)$ This set contains all elements of the form $f(n)$,
where $n$ is an element in $S$. where $n$ is an element in $S$.
For example, the set For example, the set
\[X=\{2n : n \in \mathbb{Z}\}\] \[X=\{2n : n \in \mathbb{Z}\}\]
@ -692,7 +694,7 @@ $\land$ (\key{conjunction}),
$\lor$ (\key{disjunction}), $\lor$ (\key{disjunction}),
$\Rightarrow$ (\key{implication}) and $\Rightarrow$ (\key{implication}) and
$\Leftrightarrow$ (\key{equivalence}). $\Leftrightarrow$ (\key{equivalence}).
The following table shows the meaning of the operators: The following table shows the meaning of these operators:
\begin{center} \begin{center}
\begin{tabular}{rr|rrrrrrr} \begin{tabular}{rr|rrrrrrr}
@ -705,7 +707,7 @@ $A$ & $B$ & $\lnot A$ & $\lnot B$ & $A \land B$ & $A \lor B$ & $A \Rightarrow B$
\end{tabular} \end{tabular}
\end{center} \end{center}
The negation $\lnot A$ reverses the value of an expression. The expression $\lnot A$ has the reverse value of $A$.
The expression $A \land B$ is true if both $A$ and $B$ The expression $A \land B$ is true if both $A$ and $B$
are true, are true,
and the expression $A \lor B$ is true if $A$ or $B$ or both and the expression $A \lor B$ is true if $A$ or $B$ or both
@ -741,10 +743,10 @@ but false in the set of natural numbers.
Using the notation described above, Using the notation described above,
we can express many kinds of logical propositions. we can express many kinds of logical propositions.
For example, For example,
\[\forall x ((x>2 \land \lnot P(x)) \Rightarrow (\exists a (\exists b (x = ab \land a > 1 \land b > 1))))\] \[\forall x ((x>1 \land \lnot P(x)) \Rightarrow (\exists a (\exists b (x = ab \land a > 1 \land b > 1))))\]
means that if a number $x$ is larger than 2 means that if a number $x$ is larger than 1
and not a prime number, and not a prime number,
there are numbers $a$ and $b$ then there exist numbers $a$ and $b$
that are larger than $1$ and whose product is $x$. that are larger than $1$ and whose product is $x$.
This proposition is true in the set of integers. This proposition is true in the set of integers.
@ -758,14 +760,14 @@ 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 the largest of values return 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.\]
\index{factorial} \index{factorial}
The \key{factorial} $n!$ is defined The \key{factorial} $n!$ can be defined
\[\prod_{x=1}^n x = 1 \cdot 2 \cdot 3 \cdot \ldots \cdot n\] \[\prod_{x=1}^n x = 1 \cdot 2 \cdot 3 \cdot \ldots \cdot n\]
or recursively or recursively
\[ \[
@ -777,7 +779,7 @@ n! & = & n \cdot (n-1)! \\
\index{Fibonacci number} \index{Fibonacci number}
The \key{Fibonacci numbers} arise in several situations. The \key{Fibonacci numbers} arise in many situations.
They can be defined recursively as follows: They can be defined recursively as follows:
\[ \[
\begin{array}{lcl} \begin{array}{lcl}
@ -797,12 +799,12 @@ for calculating Fibonacci numbers:
\index{logarithm} \index{logarithm}
The \key{logarithm} of a number $x$ The \key{logarithm} of a number $x$
is denoted $\log_k(x)$ where $k$ is the base is denoted $\log_k(x)$, where $k$ is the base
of the logarithm. of the logarithm.
The logarithm is defined so that According to the definition,
$\log_k(x)=a$ exactly when $k^a=x$. $\log_k(x)=a$ exactly when $k^a=x$.
A useful interpretation in algorithmics is A useful interpretation in algorithm design is
that $\log_k(x)$ equals the number of times that $\log_k(x)$ equals the number of times
we have to divide $x$ by $k$ before we reach we have to divide $x$ by $k$ before we reach
the number 1. the number 1.
@ -812,10 +814,10 @@ because 5 divisions are needed:
\[32 \rightarrow 16 \rightarrow 8 \rightarrow 4 \rightarrow 2 \rightarrow 1 \] \[32 \rightarrow 16 \rightarrow 8 \rightarrow 4 \rightarrow 2 \rightarrow 1 \]
Logarithms are often needed in the analysis of Logarithms are often needed in the analysis of
algorithms because many efficient algorithms algorithms, because many efficient algorithms
divide in half something at each step. divide in half something at each step.
Thus, we can estimate the efficiency of those algorithms Hence, we can estimate the efficiency of such algorithms
using the logarithm. using logarithms.
The logarithm of a product is The logarithm of a product is
\[\log_k(ab) = \log_k(a)+\log_k(b),\] \[\log_k(ab) = \log_k(a)+\log_k(b),\]
@ -834,7 +836,7 @@ calculate logarithms to some fixed base.
The \key{natural logarithm} $\ln(x)$ of a number $x$ The \key{natural logarithm} $\ln(x)$ of a number $x$
is a logarithm whose base is $e \approx 2{,}71828$. is a logarithm whose base is $e \approx 2{,}71828$.
Another property of the logarithm is that Another property of logarithms is that
the number of digits of a number $x$ in base $b$ is the number of digits of a number $x$ in base $b$ is
$\lfloor \log_b(x)+1 \rfloor$. $\lfloor \log_b(x)+1 \rfloor$.
For example, the representation of For example, the representation of