\chapter{Introduction} Competitive programming combines two topics: (1) design of algorithms and (2) implementation of algorithms. The \key{design of algorithms} consists of problem solving and mathematical thinking. Skills for analyzing problems and solving them using creativity is needed. An algorithm for solving a problem has to be both correct and efficient, and the core of the problem is often how to invent an efficient algorithm. Theoretical knowledge of algorithms is very important to competitive programmers. Typically, a solution for a problem is a combination of well-known techniques and new insights. The techniques that appear in competitive programming also form the basis for the scientific research of algorithms. The \key{implementation of algorithms} requires good programming skills. In competitive programming, the solutions are graded by testing an implemented algorithm using a set of test cases. Thus, it is not enough that the idea of the algorithm is correct, but the implementation has to be correct as well. Good coding style in contests is straightforward and concise. The solutions should be written quickly, because there is not much time available. Unlike in traditional software engineering, the solutions are short (usually at most some hundreds of lines) and it is not needed to maintain them after the contest. \section{Programming languages} \index{programming language} At the moment, the most popular programming languages in contests are C++, Python and Java. For example, in Google Code Jam 2016, among the best 3,000 participants, 73 \% used C++, 15 \% used Python and 10 \% used Java\footnote{\url{https://www.go-hero.net/jam/16}}. Some participants also used several languages. Many people think that C++ is the best choice for a competitive programmer, and C++ is nearly always available in contest systems. The benefits in using C++ are that it is a very efficient language and its standard library contains a large collection of data structures and algorithms. On the other hand, it is good to master several languages and know the benefits of them. For example, if big integers are needed in the problem, Python can be a good choice because it contains a built-in library for handling big integers. Still, usually the goal is to write the problems so that the use of a specific programming language is not an unfair advantage in the contest. All examples in this book are written in C++, and the data structures and algorithms in the standard library are often used. The book follows the C++11 standard that can be used in most contests nowadays. If you can't program in C++ yet, now it is a good time to start learning. \subsubsection{C++ template} A typical C++ template for competitive programming looks like this: \begin{lstlisting} #include using namespace std; int main() { // solution comes here } \end{lstlisting} The \texttt{\#include} line at the beginning of the code is a feature in the \texttt{g++} compiler that allows to include the whole standard library. Thus, it is not needed to separately include libraries such as \texttt{iostream}, \texttt{vector} and \texttt{algorithm}, but they are available automatically. The \texttt{using} line determines that the standard library can be used directly in the code. Without the \texttt{using} line we should write, for example, \texttt{std::cout}, but now it is enough to write \texttt{cout}. The code can be compiled using the following command: \begin{lstlisting} g++ -std=c++11 -O2 -Wall code.cpp -o code \end{lstlisting} This command produces a binary file \texttt{code} from the source code \texttt{code.cpp}. The compiler obeys the C++11 standard (\texttt{-std=c++11}), optimizes the code (\texttt{-O2}) and shows warnings about possible errors (\texttt{-Wall}). \section{Input and output} \index{input and output} In most contests, standard streams are used for reading input and writing output. In C++, the standard streams are \texttt{cin} for input and \texttt{cout} for output. In addition, the C functions \texttt{scanf} and \texttt{printf} can be used. The input for the program usually consists of numbers and strings that are separated with spaces and newlines. They can be read from the \texttt{cin} stream as follows: \begin{lstlisting} int a, b; string x; cin >> a >> b >> x; \end{lstlisting} This kind of code always works, assuming that there is at least one space or one newline between each element in the input. For example, the above code accepts both the following inputs: \begin{lstlisting} 123 456 apina \end{lstlisting} \begin{lstlisting} 123 456 apina \end{lstlisting} The \texttt{cout} stream is used for output as follows: \begin{lstlisting} int a = 123, b = 456; string x = "apina"; cout << a << " " << b << " " << x << "\n"; \end{lstlisting} Handling input and output is sometimes a bottleneck in the program. The following lines at the beginning of the code make input and output more efficient: \begin{lstlisting} ios_base::sync_with_stdio(0); cin.tie(0); \end{lstlisting} Note that the newline \texttt{"\textbackslash n"} works faster than \texttt{endl}, becauses \texttt{endl} always causes a flush operation. The C functions \texttt{scanf} and \texttt{printf} are an alternative to the C++ standard streams. They are usually a bit faster, but they are also more difficult to use. The following code reads two integers from the input: \begin{lstlisting} int a, b; scanf("%d %d", &a, &b); \end{lstlisting} The following code prints two integers: \begin{lstlisting} int a = 123, b = 456; printf("%d %d\n", a, b); \end{lstlisting} Sometimes the program should read a whole line from the input, possibly with spaces. This can be accomplished using the \texttt{getline} function: \begin{lstlisting} string s; getline(cin, s); \end{lstlisting} If the amount of data is unknown, the following loop can be handy: \begin{lstlisting} while (cin >> x) { // koodia } \end{lstlisting} This loop reads elements from the input one after another, until there is no more data available in the input. In some contest systems, files are used for input and output. An easy solution for this is to write the code as usual using standard streams, but add the following lines to the beginning of the code: \begin{lstlisting} freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout); \end{lstlisting} After this, the code reads the input from the file ''input.txt'' and writes the output to the file ''output.txt''. \section{Handling numbers} \index{integer} \subsubsection{Integers} The most popular integer type in competitive programming is \texttt{int}. This is a 32-bit type with value range $-2^{31} \ldots 2^{31}-1$, i.e., about $-2 \cdot 10^9 \ldots 2 \cdot 10^9$. If the type \texttt{int} is not enough, the 64-bit type \texttt{long long} can be used, with value range $-2^{63} \ldots 2^{63}-1$, i.e., about $-9 \cdot 10^{18} \ldots 9 \cdot 10^{18}$. The following code defines a \texttt{long long} variable: \begin{lstlisting} long long x = 123456789123456789LL; \end{lstlisting} The suffix \texttt{LL} means that the type of the number is \texttt{long long}. A typical error when using the type \texttt{long long} is that the type \texttt{int} is still used somewhere in the code. For example, the following code contains a subtle error: \begin{lstlisting} int a = 123456789; long long b = a*a; cout << b << "\n"; // -1757895751 \end{lstlisting} Even though the variable \texttt{b} is of type \texttt{long long}, both numbers in the expression \texttt{a*a} are of type \texttt{int} and the result is also of type \texttt{int}. Because of this, the variable \texttt{b} will contain a wrong result. The problem can be solved by changing the type of \texttt{a} to \texttt{long long} or by changing the expression to \texttt{(long long)a*a}. Usually, the problems are written so that the type \texttt{long long} is enough. Still, it is good to know that the \texttt{g++} compiler also features an 128-bit type \texttt{\_\_int128\_t} with value range $-2^{127} \ldots 2^{127}-1$, i.e., $-10^{38} \ldots 10^{38}$. However, this type is not available in all contest systems. \subsubsection{Modular arithmetic} \index{remainder} \index{modular arithmetic} We denote by $x \bmod m$ the remainder when $x$ is divided by $m$. For example, $17 \bmod 5 = 2$, because $17 = 3 \cdot 5 + 2$. Sometimes, the answer for a problem is a very big integer but it is enough to print it ''modulo $m$'', i.e., the remainder when the answer is divided by $m$ (for example, ''modulo $10^9+7$''). The idea is that even if the actual answer may be very big, it is enough to use the types \texttt{int} and \texttt{long long}. An important property of the remainder is that in addition, subtraction and multiplication, the remainder can be calculated before the operation: \[ \begin{array}{rcr} (a+b) \bmod m & = & (a \bmod m + b \bmod m) \bmod m \\ (a-b) \bmod m & = & (a \bmod m - b \bmod m) \bmod m \\ (a \cdot b) \bmod m & = & (a \bmod m \cdot b \bmod m) \bmod m \end{array} \] Thus, we can calculate the remainder after every operation and the numbers will never become too large. For example, the following code calculates $n!$, the factorial of $n$, modulo $m$: \begin{lstlisting} long long x = 1; for (int i = 2; i <= n i++) { x = (x*i)%m; } cout << x << "\n"; \end{lstlisting} Usually, the answer should be always given so that the remainder is between $0\ldots m-1$. However, in C++ and other languages, the remainder of a negative number can be negative. An easy way to make sure that this will not happen is to first calculate the remainder as usual and then add $m$ if the result is negative: \begin{lstlisting} x = x%m; if (x < 0) x += m; \end{lstlisting} However, this is only needed when there are subtractions in the code and the remainder may become negative. \subsubsection{Floating point numbers} \index{floating point number} The usual floating point types in competitive programming are the 64-bit \texttt{double} and, as an extension in the \texttt{g++} compiler, the 80-bit \texttt{long double}. In most cases, \texttt{double} is enough, but \texttt{long double} is more accurate. The required precision of the answer is usually given. The easiest way is to use the \texttt{printf} function that can be given the number of decimal places. For example, the following code prints the value of $x$ with 9 decimal places: \begin{lstlisting} printf("%.9f\n", x); \end{lstlisting} A difficulty when using floating point numbers is that some numbers cannot be represented accurately, but there will be rounding errors. For example, the result of the following code is surprising: \begin{lstlisting} double x = 0.3*3+0.1; printf("%.20f\n", x); // 0.99999999999999988898 \end{lstlisting} Because of a rounding error, the value of \texttt{x} is a bit less than 1, while the correct value would be 1. It is risky to compare floating point numbers with the \texttt{==} operator, because it is possible that the values should be equal but they are not due to rounding errors. A better way to compare floating point numbers is to assume that two numbers are equal if the difference between them is $\varepsilon$, where $\varepsilon$ is a small number. In practice, the numbers can be compared as follows ($\varepsilon=10^{-9}$): \begin{lstlisting} if (abs(a-b) < 1e-9) { // a and b are equal } \end{lstlisting} Note that while floating point numbers are inaccurate, integers up to a certain limit can be still represented accurately. For example, using \texttt{double}, it is possible to accurately represent all integers having absolute value at most $2^{53}$. \section{Shortening code} Short code is ideal in competitive programming, because the algorithm should be implemented as fast as possible. Because of this, competitive programmers often define shorter names for datatypes and other parts of code. \subsubsection{Type names} \index{tuppdef@\texttt{typedef}} Using the command \texttt{typedef} it is possible to give a shorter name to a datatype. For example, the name \texttt{long long} is long, so we can define a shorter name \texttt{ll}: \begin{lstlisting} typedef long long ll; \end{lstlisting} After this, the code \begin{lstlisting} long long a = 123456789; long long b = 987654321; cout << a*b << "\n"; \end{lstlisting} can be shortened as follows: \begin{lstlisting} ll a = 123456789; ll b = 987654321; cout << a*b << "\n"; \end{lstlisting} The command \texttt{typedef} can also be used with more complex types. For example, the following code gives the name \texttt{vi} for a vector of integers, and the name \texttt{pi} for a pair that contains two integers. \begin{lstlisting} typedef vector vi; typedef pair pi; \end{lstlisting} \subsubsection{Macros} \index{macro} Another way to shorten the code is to define \key{macros}. A macro means that certain strings in the code will be changed before the compilation. In C++, macros are defined using the command \texttt{\#define}. For example, we can define the following macros: \begin{lstlisting} #define F first #define S second #define PB push_back #define MP make_pair \end{lstlisting} After this, the code \begin{lstlisting} v.push_back(make_pair(y1,x1)); v.push_back(make_pair(y2,x2)); int d = v[i].first+v[i].second; \end{lstlisting} can be shortened as follows: \begin{lstlisting} v.PB(MP(y1,x1)); v.PB(MP(y2,x2)); int d = v[i].F+v[i].S; \end{lstlisting} It is also possible to define a macro with parameters which makes it possible to shorten loops and other structures in the code. For example, we can define the following macro: \begin{lstlisting} #define REP(i,a,b) for (int i = a; i <= b; i++) \end{lstlisting} After this, the code \begin{lstlisting} for (int i = 1; i <= n; i++) { haku(i); } \end{lstlisting} can be shortened as follows: \begin{lstlisting} REP(i,1,n) { haku(i); } \end{lstlisting} \section{Mathematics} Mathematics plays an important role in competitive programming, and it is not possible to become a successful competitive programmer without good skills in mathematics. This section covers some important mathematical concepts and formulas that are needed later in the book. \subsubsection{Summakaavat} Jokaiselle summalle muotoa \[\sum_{x=1}^n x^k = 1^k+2^k+3^k+\ldots+n^k\] on olemassa laskukaava, kun $k$ on jokin positiivinen kokonaisluku. Tällainen laskukaava on aina astetta $k+1$ oleva polynomi. Esimerkiksi \[\sum_{x=1}^n x = 1+2+3+\ldots+n = \frac{n(n+1)}{2}\] ja \[\sum_{x=1}^n x^2 = 1^2+2^2+3^2+\ldots+n^2 = \frac{n(n+1)(2n+1)}{6}.\] \key{Aritmeettinen summa} on summa, \index{aritmeettinen summa@aritmeettinen summa} jossa jokaisen vierekkäisen luvun erotus on vakio. Esimerkiksi \[3+7+11+15\] on aritmeettinen summa, jossa vakio on 4. Aritmeettinen summa voidaan laskea kaavalla \[\frac{n(a+b)}{2},\] jossa summan ensimmäinen luku on $a$, viimeinen luku on $b$ ja lukujen määrä on $n$. Esimerkiksi \[3+7+11+15=\frac{4 \cdot (3+15)}{2} = 36.\] Kaava perustuu siihen, että summa muodostuu $n$ luvusta ja luvun suuruus on keskimäärin $(a+b)/2$. \index{geometrinen summa@geometrinen summa} \key{Geometrinen summa} on summa, jossa jokaisen vierekkäisen luvun suhde on vakio. Esimerkiksi \[3+6+12+24\] on geometrinen summa, jossa vakio on 2. Geometrinen summa voidaan laskea kaavalla \[\frac{bx-a}{x-1},\] jossa summan ensimmäinen luku on $a$, viimeinen luku on $b$ ja vierekkäisten lukujen suhde on $x$. Esimerkiksi \[3+6+12+24=\frac{24 \cdot 2 - 3}{2-1} = 45.\] Geometrisen summan kaavan voi johtaa merkitsemällä \[ S = a + ax + ax^2 + \cdots + b .\] Kertomalla molemmat puolet $x$:llä saadaan \[ xS = ax + ax^2 + ax^3 + \cdots + bx,\] josta kaava seuraa ratkaisemalla yhtälön \[ xS-S = bx-a.\] Geometrisen summan erikoistapaus on usein kätevä kaava \[1+2+4+8+\ldots+2^{n-1}=2^n-1.\] % Geometrisen summan sukulainen on % \[x+2x^2+3x^3+\cdots+k x^k = \frac{kx^{k+2}-(k+1)x^{k+1}+x}{(x-1)^2}. \] \index{harmoninen summa@harmoninen summa} \key{Harmoninen summa} on summa muotoa \[ \sum_{x=1}^n \frac{1}{x} = 1+\frac{1}{2}+\frac{1}{3}+\ldots+\frac{1}{n}.\] Yläraja harmonisen summan suuruudelle on $\log_2(n)+1$. Summaa voi näet arvioida ylöspäin muuttamalla jokaista termiä $1/k$ niin, että $k$:ksi tulee alempi 2:n potenssi. Esimerkiksi tapauksessa $n=6$ arvioksi tulee \[ 1+\frac{1}{2}+\frac{1}{3}+\frac{1}{4}+\frac{1}{5}+\frac{1}{6} \le 1+\frac{1}{2}+\frac{1}{2}+\frac{1}{4}+\frac{1}{4}+\frac{1}{4}.\] Tämän seurauksena summa jakaantuu $\log_2(n)+1$ osaan ($1$, $2 \cdot 1/2$, $4 \cdot 1/4$, jne.), joista jokaisen summa on enintään 1. \subsubsection{Joukko-oppi} \index{joukko-oppi} \index{joukko@joukko} \index{leikkaus@leikkaus} \index{yhdiste@yhdiste} \index{erotus@erotus} \index{osajoukko@osajoukko} \index{perusjoukko} \key{Joukko} on kokoelma alkioita. Esimerkiksi joukko \[X=\{2,4,7\}\] sisältää alkiot 2, 4 ja 7. Merkintä $\emptyset$ tarkoittaa tyhjää joukkoa. Joukon $S$ koko eli alkoiden määrä on $|S|$. Esimerkiksi äskeisessä joukossa $|X|=3$. Merkintä $x \in S$ tarkoittaa, että alkio $x$ on joukossa $S$, ja merkintä $x \notin S$ tarkoittaa, että alkio $x$ ei ole joukossa $S$. Esimerkiksi äskeisessä joukossa \[4 \in X \hspace{10px}\textrm{ja}\hspace{10px} 5 \notin X.\] \begin{samepage} Uusia joukkoja voidaan muodostaa joukko-operaatioilla seuraavasti: \begin{itemize} \item \key{Leikkaus} $A \cap B$ sisältää alkiot, jotka ovat molemmissa joukoista $A$ ja $B$. Esimerkiksi jos $A=\{1,2,5\}$ ja $B=\{2,4\}$, niin $A \cap B = \{2\}$. \item \key{Yhdiste} $A \cup B$ sisältää alkiot, jotka ovat ainakin toisessa joukoista $A$ ja $B$. Esimerkiksi jos $A=\{3,7\}$ ja $B=\{2,3,8\}$, niin $A \cup B = \{2,3,7,8\}$. \item \key{Komplementti} $\bar A$ sisältää alkiot, jotka eivät ole joukossa $A$. Komplementin tulkinta riippuu siitä, mikä on \key{perusjoukko} eli joukko, jossa on kaikki mahdolliset alkiot. Esimerkiksi jos $A=\{1,2,5,7\}$ ja perusjoukko on $P=\{1,2,\ldots,10\}$, niin $\bar A = \{3,4,6,8,9,10\}$. \item \key{Erotus} $A \setminus B = A \cap \bar B$ sisältää alkiot, jotka ovat joukossa $A$ mutta eivät joukossa $B$. Huomaa, että $B$:ssä voi olla alkioita, joita ei ole $A$:ssa. Esimerkiksi jos $A=\{2,3,7,8\}$ ja $B=\{3,5,8\}$, niin $A \setminus B = \{2,7\}$. \end{itemize} \end{samepage} Merkintä $A \subset S$ tarkoittaa, että $A$ on $S$:n \key{osajoukko} eli jokainen $A$:n alkio esiintyy $S$:ssä. Joukon $S$ osajoukkojen yhteismäärä on $2^{|S|}$. Esimerkiksi joukon $\{2,4,7\}$ osajoukot ovat \begin{center} $\emptyset$, $\{2\}$, $\{4\}$, $\{7\}$, $\{2,4\}$, $\{2,7\}$, $\{4,7\}$ ja $\{2,4,7\}$. \end{center} Usein esiintyviä joukkoja ovat \begin{itemize}[noitemsep] \item $\mathbb{N}$ (luonnolliset luvut), \item $\mathbb{Z}$ (kokonaisluvut), \item $\mathbb{Q}$ (rationaaliluvut) ja \item $\mathbb{R}$ (reaaliluvut). \end{itemize} Luonnollisten lukujen joukko $\mathbb{N}$ voidaan määritellä tilanteesta riippuen kahdella tavalla: joko $\mathbb{N}=\{0,1,2,\ldots\}$ tai $\mathbb{N}=\{1,2,3,...\}$. Joukon voi muodostaa myös säännöllä muotoa \[\{f(n) : n \in S\},\] missä $f(n)$ on jokin funktio. Tällainen joukko sisältää kaikki alkiot $f(n)$, jossa $n$ on valittu joukosta $S$. Esimerkiksi joukko \[X=\{2n : n \in \mathbb{Z}\}\] sisältää kaikki parilliset kokonaisluvut. \subsubsection{Logiikka} \index{logiikka@logiikka} \index{negaatio@negaatio} \index{konjunktio@konjunktio} \index{disjunktio@disjunktio} \index{implikaatio@implikaatio} \index{ekvivalenssi@ekvivalenssi} Loogisen lausekkeen arvo on joko \key{tosi} (1) tai \key{epätosi} (0). Tärkeimmät loogiset operaatiot ovat $\lnot$ (\key{negaatio}), $\land$ (\key{konjunktio}), $\lor$ (\key{disjunktio}), $\Rightarrow$ (\key{implikaatio}) sekä $\Leftrightarrow$ (\key{ekvivalenssi}). Seuraava taulukko näyttää operaatioiden merkityksen: \begin{center} \begin{tabular}{rr|rrrrrrr} $A$ & $B$ & $\lnot A$ & $\lnot B$ & $A \land B$ & $A \lor B$ & $A \Rightarrow B$ & $A \Leftrightarrow B$ \\ \hline 0 & 0 & 1 & 1 & 0 & 0 & 1 & 1 \\ 0 & 1 & 1 & 0 & 0 & 1 & 1 & 0 \\ 1 & 0 & 0 & 1 & 0 & 1 & 0 & 0 \\ 1 & 1 & 0 & 0 & 1 & 1 & 1 & 1 \\ \end{tabular} \end{center} Negaatio $\lnot A$ muuttaa lausekkeen käänteiseksi. Lauseke $A \land B$ on tosi, jos molemmat $A$ ja $B$ ovat tosia, ja lauseke $A \lor B$ on tosi, jos $A$ tai $B$ on tosi. Lauseke $A \Rightarrow B$ on tosi, jos $A$:n ollessa tosi myös $B$ on aina tosi. Lauseke $A \Leftrightarrow B$ on tosi, jos $A$:n ja $B$:n totuusarvo on sama. \index{predikaatti@predikaatti} \key{Predikaatti} on lauseke, jonka arvo on tosi tai epätosi riippuen sen parametreista. Yleensä predikaattia merkitään suurella kirjaimella. Esimerkiksi voimme määritellä predikaatin $P(x)$, joka on tosi tarkalleen silloin, kun $x$ on alkuluku. Tällöin esimerkiksi $P(7)$ on tosi, kun taas $P(8)$ on epätosi. \index{kvanttori@kvanttori} \key{Kvanttori} ilmaisee, että looginen lauseke liittyy jollakin tavalla joukon alkioihin. Tavalliset kvanttorit ovat $\forall$ (\key{kaikille}) ja $\exists$ (\key{on olemassa}). Esimerkiksi \[\forall x (\exists y (y < x))\] tarkoittaa, että jokaiselle joukon alkiolle $x$ on olemassa jokin joukon alkio $y$ niin, että $y$ on $x$:ää pienempi. Tämä pätee kokonaislukujen joukossa, mutta ei päde luonnollisten lukujen joukossa. Yllä esitettyjen merkintöjä avulla on mahdollista esittää monenlaisia loogisia väitteitä. Esimerkiksi \[\forall x ((x>2 \land \lnot P(x)) \Rightarrow (\exists a (\exists b (x = ab \land a > 1 \land b > 1))))\] tarkoittaa, että jos luku $x$ on suurempi kuin 2 eikä ole alkuluku, niin on olemassa luvut $a$ ja $b$, joiden tulo on $x$ ja jotka molemmat ovat suurempia kuin 1. Tämä väite pitää paikkansa kokonaislukujen joukossa. \subsubsection{Funktioita} Funktio $\lfloor x \rfloor$ pyöristää luvun $x$ alaspäin kokonaisluvuksi ja funktio $\lceil x \rceil$ pyöristää luvun $x$ ylöspäin kokonaisluvuksi. Esimerkiksi \[ \lfloor 3/2 \rfloor = 1 \hspace{10px} \textrm{ja} \hspace{10px} \lceil 3/2 \rceil = 2.\] Funktiot $\min(x_1,x_2,\ldots,x_n)$ ja $\max(x_1,x_2,\ldots,x_n)$ palauttavat pienimmän ja suurimman arvoista $x_1,x_2,\ldots,x_n$. Esimerkiksi \[ \min(1,2,3)=1 \hspace{10px} \textrm{ja} \hspace{10px} \max(1,2,3)=3.\] \index{kertoma@kertoma} \key{Kertoma} $n!$ määritellään \[\prod_{x=1}^n x = 1 \cdot 2 \cdot 3 \cdot \ldots \cdot n\] tai vaihtoehtoisesti rekursiivisesti \[ \begin{array}{lcl} 0! & = & 1 \\ n! & = & n \cdot (n-1)! \\ \end{array} \] \index{Fibonaccin luku@Fibonaccin luku} \key{Fibonaccin luvut} esiintyvät monissa erilaisissa yhteyksissä. Ne määritellään seuraavasti rekursiivisesti: \[ \begin{array}{lcl} f(0) & = & 0 \\ f(1) & = & 1 \\ f(n) & = & f(n-1)+f(n-2) \\ \end{array} \] Ensimmäiset Fibonaccin luvut ovat \[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, \ldots\] Fibonaccin lukujen laskemiseen on olemassa myös suljetun muodon kaava \[f(n)=\frac{(1 + \sqrt{5})^n - (1-\sqrt{5})^n}{2^n \sqrt{5}}.\] \subsubsection{Logaritmi} \index{logaritmi@logaritmi} Luvun $x$ \key{logaritmi} merkitään $\log_k(x)$, missä $k$ on logaritmin kantaluku. Logaritmin määritelmän mukaan $\log_k(x)=a$ tarkalleen silloin, kun $k^a=x$. Algoritmiikassa hyödyllinen tulkinta on, että logaritmi $\log_k(x)$ ilmaisee, montako kertaa lukua $x$ täytyy jakaa $k$:lla, ennen kuin tulos on 1. Esimerkiksi $\log_2(32)=5$, koska lukua 32 täytyy jakaa 2:lla 5 kertaa: \[32 \rightarrow 16 \rightarrow 8 \rightarrow 4 \rightarrow 2 \rightarrow 1 \] Logaritmi tulee usein vastaan algoritmien analyysissa, koska monessa tehokkaassa algoritmissa jokin asia puolittuu joka askeleella. Niinpä logaritmin avulla voi arvioida algoritmin tehokkuutta. Logaritmille pätee kaava \[\log_k(ab) = \log_k(a)+\log_k(b),\] josta seuraa edelleen \[\log_k(x^n) = n \cdot \log_k(x).\] Samoin logaritmille pätee \[\log_k\Big(\frac{a}{b}\Big) = \log_k(a)-\log_k(b).\] Lisäksi on voimassa kaava \[\log_u(x) = \frac{\log_k(x)}{\log_k(u)},\] minkä ansiosta logaritmeja voi laskea mille tahansa kantaluvulle, jos on keino laskea logaritmeja jollekin kantaluvulle. \index{luonnollinen logaritmi@luonnollinen logaritmi} \index{Neperin luku@Neperin luku} Luvun $x$ \key{luonnollinen logaritmi} $\ln(x)$ on logaritmi, jonka kantaluku on \key{Neperin luku} $e \approx 2{,}71828$. Vielä yksi logaritmin ominaisuus on, että luvun $x$ numeroiden määrä $b$-kantaisessa lukujärjestelmässä on $\lfloor \log_b(x)+1 \rfloor$. Esimerkiksi luvun $123$ esitys 2-järjestelmässä on 1111011 ja $\lfloor \log_2(123)+1 \rfloor = 7$.