Skip to content

Commit fab2d0a

Browse files
committed
some fixes
1 parent d466085 commit fab2d0a

File tree

6 files changed

+94
-58
lines changed

6 files changed

+94
-58
lines changed

src/algebra/binary-exp.md

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
<!--?title Binary Exponentiation-->
1+
---
2+
title: Binary Exponentiation
3+
hide:
4+
- navigation
5+
---
26
# Binary Exponentiation
37

48
Binary exponentiation (also known as exponentiation by squaring) is a trick which allows to calculate $a^n$ using only $O(\log n)$ multiplications (instead of $O(n)$ multiplications required by the naive approach).
@@ -30,9 +34,9 @@ So we only need to know a fast way to compute those.
3034
Luckily this is very easy, since an element in the sequence is just the square of the previous element.
3135

3236
$$\begin{align}
33-
3^1 &= 3 \\\\
34-
3^2 &= \left(3^1\right)^2 = 3^2 = 9 \\\\
35-
3^4 &= \left(3^2\right)^2 = 9^2 = 81 \\\\
37+
3^1 &= 3 \\
38+
3^2 &= \left(3^1\right)^2 = 3^2 = 9 \\
39+
3^4 &= \left(3^2\right)^2 = 9^2 = 81 \\
3640
3^8 &= \left(3^4\right)^2 = 81^2 = 6561
3741
\end{align}$$
3842

@@ -44,9 +48,9 @@ The final complexity of this algorithm is $O(\log n)$: we have to compute $\log
4448
The following recursive approach expresses the same idea:
4549

4650
$$a^n = \begin{cases}
47-
1 &\text{if } n == 0 \\\\
48-
\left(a^{\frac{n}{2}}\right)^2 &\text{if } n > 0 \text{ and } n \text{ even}\\\\
49-
\left(a^{\frac{n - 1}{2}}\right)^2 \cdot a &\text{if } n > 0 \text{ and } n \text{ odd}\\\\
51+
1 &\text{if } n == 0 \\
52+
\left(a^{\frac{n}{2}}\right)^2 &\text{if } n > 0 \text{ and } n \text{ even}\\
53+
\left(a^{\frac{n - 1}{2}}\right)^2 \cdot a &\text{if } n > 0 \text{ and } n \text{ odd}\\
5054
\end{cases}$$
5155

5256
## Implementation
@@ -107,7 +111,7 @@ long long binpow(long long a, long long b, long long m) {
107111
}
108112
```
109113
110-
**Note:** If $m$ is a prime number we can speed up a bit this algorithm by calculating $x ^ {n \mod (m-1)}$ instead of $x ^ n$.
114+
**Note:** If $m$ is a prime number we can speed up a bit this algorithm by calculating $x^{n \bmod (m-1)}$ instead of $x ^ n$.
111115
This follows directly from [Fermat's little theorem](module-inverse.md#toc-tgt-2).
112116
113117
### Effective computation of Fibonacci numbers
@@ -122,7 +126,7 @@ the transition from $F_i$ and $F_{i+1}$ to $F_{i+1}$ and $F_{i+2}$.
122126
For example, applying this transformation to the pair $F_0$ and $F_1$ would change it into $F_1$ and $F_2$.
123127
Therefore, we can raise this transformation matrix to the $n$-th power to find $F_n$ in time complexity $O(\log n)$.
124128
125-
### Applying a permutation $k$ times
129+
### Applying a permutation $k$ times { data-toc-label='Applying a permutation <script type="math/tex">k</script> times' }
126130
127131
**Problem:** You are given a sequence of length $n$. Apply to it a given permutation $k$ times.
128132
@@ -143,20 +147,20 @@ Therefore, we can raise this transformation matrix to the $n$-th power to find $
143147
As you can see, each of the transformations can be represented as a linear operation on the coordinates. Thus, a transformation can be written as a $4 \times 4$ matrix of the form:
144148
145149
$$\begin{pmatrix}
146-
a_{11} & a_ {12} & a_ {13} & a_ {14} \\\
147-
a_{21} & a_ {22} & a_ {23} & a_ {24} \\\
148-
a_{31} & a_ {32} & a_ {33} & a_ {34} \\\
149-
a_{41} & a_ {42} & a_ {43} & a_ {44} \\\
150+
a_{11} & a_ {12} & a_ {13} & a_ {14} \\
151+
a_{21} & a_ {22} & a_ {23} & a_ {24} \\
152+
a_{31} & a_ {32} & a_ {33} & a_ {34} \\
153+
a_{41} & a_ {42} & a_ {43} & a_ {44}
150154
\end{pmatrix}$$
151155
152156
that, when multiplied by a vector with the old coordinates and an unit gives a new vector with the new coordinates and an unit:
153157
154158
$$\begin{pmatrix} x & y & z & 1 \end{pmatrix} \cdot
155159
\begin{pmatrix}
156-
a_{11} & a_ {12} & a_ {13} & a_ {14} \\\
157-
a_{21} & a_ {22} & a_ {23} & a_ {24} \\\
158-
a_{31} & a_ {32} & a_ {33} & a_ {34} \\\
159-
a_{41} & a_ {42} & a_ {43} & a_ {44} \\\
160+
a_{11} & a_ {12} & a_ {13} & a_ {14} \\
161+
a_{21} & a_ {22} & a_ {23} & a_ {24} \\
162+
a_{31} & a_ {32} & a_ {33} & a_ {34} \\
163+
a_{41} & a_ {42} & a_ {43} & a_ {44}
160164
\end{pmatrix}
161165
= \begin{pmatrix} x' & y' & z' & 1 \end{pmatrix}$$
162166
@@ -167,34 +171,34 @@ Here are some examples of how transformations are represented in matrix form:
167171
* Shift operation: shift $x$ coordinate by $5$, $y$ coordinate by $7$ and $z$ coordinate by $9$.
168172
169173
$$\begin{pmatrix}
170-
1 & 0 & 0 & 0 \\\
171-
0 & 1 & 0 & 0 \\\
172-
0 & 0 & 1 & 0 \\\
173-
5 & 7 & 9 & 1 \\\
174+
1 & 0 & 0 & 0 \\
175+
0 & 1 & 0 & 0 \\
176+
0 & 0 & 1 & 0 \\
177+
5 & 7 & 9 & 1
174178
\end{pmatrix}$$
175179
176180
* Scaling operation: scale the $x$ coordinate by $10$ and the other two by $5$.
177181
178182
$$\begin{pmatrix}
179-
10 & 0 & 0 & 0 \\\
180-
0 & 5 & 0 & 0 \\\
181-
0 & 0 & 5 & 0 \\\
182-
0 & 0 & 0 & 1 \\\
183+
10 & 0 & 0 & 0 \\
184+
0 & 5 & 0 & 0 \\
185+
0 & 0 & 5 & 0 \\
186+
0 & 0 & 0 & 1
183187
\end{pmatrix}$$
184188
185189
* Rotation operation: rotate $\theta$ degrees around the $x$ axis following the right-hand rule (counter-clockwise direction).
186190
187191
$$\begin{pmatrix}
188-
1 & 0 & 0 & 0 \\\
189-
0 & \cos \theta & -\sin \theta & 0 \\\
190-
0 & \sin \theta & \cos \theta & 0 \\\
191-
0 & 0 & 0 & 1 \\\
192+
1 & 0 & 0 & 0 \\
193+
0 & \cos \theta & -\sin \theta & 0 \\
194+
0 & \sin \theta & \cos \theta & 0 \\
195+
0 & 0 & 0 & 1
192196
\end{pmatrix}$$
193197
194198
Now, once every transformation is described as a matrix, the sequence of transformations can be described as a product of these matrices, and a "loop" of $k$ repetitions can be described as the matrix raised to the power of $k$ (which can be calculated using binary exponentiation in $O(\log{k})$). This way, the matrix which represents all transformations can be calculated first in $O(m \log{k})$, and then it can be applied to each of the $n$ points in $O(n)$ for a total complexity of $O(n + m \log{k})$.
195199
196200
197-
### Number of paths of length $k$ in a graph
201+
### Number of paths of length $k$ in a graph { data-toc-label='Number of paths of length <script type="math/tex">k</script> in a graph' }
198202
199203
**Problem:** Given a directed unweighted graph of $n$ vertices, find the number of paths of length $k$ from any vertex $u$ to any other vertex $v$.
200204
@@ -205,15 +209,15 @@ Instead of the usual operation of multiplying two matrices, a modified one shoul
205209
instead of multiplication, both values are added, and instead of a summation, a minimum is taken.
206210
That is: $result_{ij} = \min\limits_{1\ \leq\ k\ \leq\ n}(a_{ik} + b_{kj})$.
207211
208-
### Variation of binary exponentiation: multiplying two numbers modulo $m$
212+
### Variation of binary exponentiation: multiplying two numbers modulo $m$ { data-toc-label='Variation of binary exponentiation: multiplying two numbers modulo <script type="math/tex">m</script>' }
209213
210214
**Problem:** Multiply two numbers $a$ and $b$ modulo $m$. $a$ and $b$ fit in the built-in data types, but their product is too big to fit in a 64-bit integer. The idea is to compute $a \cdot b \pmod m$ without using bignum arithmetics.
211215
212216
**Solution:** We simply apply the binary construction algorithm described above, only performing additions instead of multiplications. In other words, we have "expanded" the multiplication of two numbers to $O (\log m)$ operations of addition and multiplication by two (which, in essence, is an addition).
213217
214218
$$a \cdot b = \begin{cases}
215-
0 &\text{if }a = 0 \\\\
216-
2 \cdot \frac{a}{2} \cdot b &\text{if }a > 0 \text{ and }a \text{ even} \\\\
219+
0 &\text{if }a = 0 \\
220+
2 \cdot \frac{a}{2} \cdot b &\text{if }a > 0 \text{ and }a \text{ even} \\
217221
2 \cdot \frac{a-1}{2} \cdot b + b &\text{if }a > 0 \text{ and }a \text{ odd}
218222
\end{cases}$$
219223

src/algebra/euclid-algorithm.md

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1-
<!--?title Euclidean algorithm for computing the greatest common divisor -->
1+
---
2+
title: Euclidean algorithm for computing the greatest common divisor
3+
hide:
4+
- navigation
5+
---
26
# Euclidean algorithm for computing the greatest common divisor
37

48
Given two non-negative integers $a$ and $b$, we have to find their **GCD** (greatest common divisor), i.e. the largest number which is a divisor of both $a$ and $b$.
59
It's commonly denoted by $\gcd(a, b)$. Mathematically it is defined as:
10+
611
$$\gcd(a, b) = \max_ {k = 1 \dots \infty ~ : ~ k \mid a ~ \wedge k ~ \mid b} k.$$
12+
713
(here the symbol "$\mid$" denotes divisibility, i.e. "$k \mid a$" means "$k$ divides $a$")
814

915
When one of the numbers is zero, while the other is non-zero, their greatest common divisor, by definition, is the second number. When both numbers are zero, their greatest common divisor is undefined (it can be any arbitrarily large number), but we can define it to be zero. Which gives us a simple rule: if one of the numbers is zero, the greatest common divisor is the other number.
@@ -16,7 +22,7 @@ The algorithm was first described in Euclid's "Elements" (circa 300 BC), but it
1622

1723
The algorithm is extremely simple:
1824

19-
$$\gcd(a, b) = \begin{cases}a,&\text{if }b = 0 \\\\ \gcd(b, a \bmod b),&\text{otherwise.}\end{cases}$$
25+
$$\gcd(a, b) = \begin{cases}a,&\text{if }b = 0 \\ \gcd(b, a \bmod b),&\text{otherwise.}\end{cases}$$
2026

2127
## Implementation
2228

@@ -60,12 +66,15 @@ We will show that the value on the left side of the equation divides the value o
6066
Let $d = \gcd(a, b)$. Then by definition $d\mid a$ and $d\mid b$.
6167
6268
Now let's represent the remainder of the division of $a$ by $b$ as follows:
69+
6370
$$a \bmod b = a - b \cdot \Bigl\lfloor\dfrac{a}{b}\Bigr\rfloor$$
6471
6572
From this it follows that $d \mid (a \bmod b)$, which means we have the system of divisibilities:
66-
$$\begin{cases}d \mid b,\\\\ d \mid (a \mod b)\end{cases}$$
73+
74+
$$\begin{cases}d \mid b,\\ d \mid (a \mod b)\end{cases}$$
6775
6876
Now we use the fact that for any three numbers $p$, $q$, $r$, if $p\mid q$ and $p\mid r$ then $p\mid \gcd(q, r)$. In our case, we get:
77+
6978
$$d = \gcd(a, b) \mid \gcd(b, a \mod b)$$
7079
7180
Thus we have shown that the left side of the original equation divides the right. The second half of the proof is similar.
@@ -83,6 +92,7 @@ Given that Fibonacci numbers grow exponentially, we get that the Euclidean algor
8392
## Least common multiple
8493
8594
Calculating the least common multiple (commonly denoted **LCM**) can be reduced to calculating the GCD with the following simple formula:
95+
8696
$$\text{lcm}(a, b) = \frac{a \cdot b}{\gcd(a, b)}$$
8797
8898
Thus, LCM can be calculated using the Euclidean algorithm with the same time complexity:
@@ -128,7 +138,7 @@ int gcd(int a, int b) {
128138
```
129139
130140
Notice, that such an optimization is usually not necessary, and most programming languages already have a GCD function in their standard libraries.
131-
E.g. C++17 has such a function in the `numeric` header.
141+
E.g. C++17 has such a function `std::gcd` in the `numeric` header.
132142
133143
## Practice Problems
134144

src/algebra/extended-euclid-algorithm.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
<!--?title Extended Euclidean Algorithm -->
1+
---
2+
title: Extended Euclidean Algorithm
3+
hide:
4+
- navigation
5+
---
26
# Extended Euclidean Algorithm
37

48
While the [Euclidean algorithm](euclid-algorithm.md) calculates only the greatest common divisor (GCD) of two integers $a$ and $b$, the extended version also finds a way to represent GCD in terms of $a$ and $b$, i.e. coefficients $x$ and $y$ for which:
@@ -44,13 +48,13 @@ $$g = a \cdot y_1 + b \cdot \left( x_1 - y_1 \cdot \left\lfloor \frac{a}{b} \rig
4448
We found the values of $x$ and $y$:
4549

4650
$$\begin{cases}
47-
x = y_1 \\\\
51+
x = y_1 \\
4852
y = x_1 - y_1 \cdot \left\lfloor \frac{a}{b} \right\rfloor
4953
\end{cases} $$
5054

5155
## Implementation
5256

53-
```cpp extended_gcd
57+
```{.cpp file=extended_gcd}
5458
int gcd(int a, int b, int& x, int& y) {
5559
if (b == 0) {
5660
x = 1;
@@ -74,7 +78,7 @@ This implementation of extended Euclidean algorithm produces correct results for
7478
It's also possible to write the Extended Euclidean algorithm in an iterative way.
7579
Because it avoids recursion, the code will run a little bit faster than the recursive one.
7680
77-
```cpp extended_gcd_iter
81+
```{.cpp file=extended_gcd_iter}
7882
int gcd(int a, int b, int& x, int& y) {
7983
x = 1, y = 0;
8084
int x1 = 0, y1 = 1, a1 = a, b1 = b;

src/algebra/fft.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
<!--?title Fast Fourier transform -->
1+
---
2+
title: Fast Fourier transform
3+
---
24
# Fast Fourier transform
35

46
In this article we will discuss an algorithm that allows us to multiply two polynomials of length $n$ in $O(n \log n)$ time, which is better than the trivial multiplication which takes $O(n^2)$ time.

src/algebra/fibonacci-numbers.md

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
<!--?title Fibonacci Numbers -->
2-
1+
---
2+
title: Fibonacci Numbers
3+
hide:
4+
- navigation
5+
---
36
# Fibonacci Numbers
47

58
The Fibonacci sequence is defined as follows:
@@ -15,20 +18,24 @@ $$0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...$$
1518
Fibonacci numbers possess a lot of interesting properties. Here are a few of them:
1619

1720
* Cassini's identity:
18-
$$F_{n-1} F_{n+1} - F_n^2 = (-1)^n$$
21+
22+
$$F_{n-1} F_{n+1} - F_n^2 = (-1)^n$$
1923

2024
* The "addition" rule:
21-
$$F_{n+k} = F_k F_{n+1} + F_{k-1} F_n$$
25+
26+
$$F_{n+k} = F_k F_{n+1} + F_{k-1} F_n$$
2227

2328
* Applying the previous identity to the case $k = n$, we get:
24-
$$F_{2n} = F_n (F_{n+1} + F_{n-1})$$
29+
30+
$$F_{2n} = F_n (F_{n+1} + F_{n-1})$$
2531

2632
* From this we can prove by induction that for any positive integer $k$, $F_{nk}$ is multiple of $F_n$.
2733

2834
* The inverse is also true: if $F_m$ is multiple of $F_n$, then $m$ is multiple of $n$.
2935

3036
* GCD identity:
31-
$$GCD(F_m, F_n) = F_{GCD(m, n)}$$
37+
38+
$$GCD(F_m, F_n) = F_{GCD(m, n)}$$
3239

3340
* Fibonacci numbers are the worst possible inputs for Euclidean algorithm (see Lame's theorem in [Euclidean algorithm](euclid-algorithm.md))
3441

@@ -46,11 +53,11 @@ The code will be appended by a $1$ do indicate the end of the code word.
4653
Notice that this is the only occurrence where two consecutive 1-bits appear.
4754

4855
$$\begin{eqnarray}
49-
1 &=& 1 &=& F_2 &=& (11)_F \\\
50-
2 &=& 2 &=& F_3 &=& (011)_F \\\
51-
6 &=& 5 + 1 &=& F_5 + F_2 &=& (10011)_F \\\
52-
8 &=& 8 &=& F_6 &=& (000011)_F \\\
53-
9 &=& 8 + 1 &=& F_6 + F_2 &=& (100011)_F \\\
56+
1 &=& 1 &=& F_2 &=& (11)_F \\
57+
2 &=& 2 &=& F_3 &=& (011)_F \\
58+
6 &=& 5 + 1 &=& F_5 + F_2 &=& (10011)_F \\
59+
8 &=& 8 &=& F_6 &=& (000011)_F \\
60+
9 &=& 8 + 1 &=& F_6 + F_2 &=& (100011)_F \\
5461
19 &=& 13 + 5 + 1 &=& F_7 + F_5 + F_2 &=& (1001011)_F
5562
\end{eqnarray}$$
5663

@@ -101,10 +108,12 @@ Thus, in order to find $F_n$, we must raise the matrix $P$ to $n$. This can be d
101108
### Fast Doubling Method
102109

103110
Using above method we can find these equations:
111+
104112
$$ \begin{array}{rll}
105-
F_{2k} &= F_k \left( 2F_{k+1} - F_{k} \right). \\\
113+
F_{2k} &= F_k \left( 2F_{k+1} - F_{k} \right). \\
106114
F_{2k+1} &= F_{k+1}^2 + F_{k}^2.
107115
\end{array}$$
116+
108117
Thus using above two equations Fibonacci numbers can be calculated easily by the following code:
109118

110119
```cpp

src/algebra/linear-diophantine-equation.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
<!--?title Linear Diophantine Equation-->
1+
---
2+
title: Linear Diophantine Equation
3+
hide:
4+
- navigation
5+
---
26
# Linear Diophantine Equation
37

48
A Linear Diophantine Equation (in two variables) is an equation of the general form:
@@ -33,13 +37,14 @@ $$a \cdot x_g \cdot \frac{c}{g} + b \cdot y_g \cdot \frac{c}{g} = c$$
3337
Therefore one of the solutions of the Diophantine equation is:
3438

3539
$$x_0 = x_g \cdot \frac{c}{g},$$
40+
3641
$$y_0 = y_g \cdot \frac{c}{g}.$$
3742

3843
The above idea still works when $a$ or $b$ or both of them are negative. We only need to change the sign of $x_0$ and $y_0$ when necessary.
3944

4045
Finally, we can implement this idea as follows (note that this code does not consider the case $a = b = 0$):
4146

42-
```cpp linear_diophantine_any
47+
```{.cpp file=linear_diophantine_any}
4348
int gcd(int a, int b, int& x, int& y) {
4449
if (b == 0) {
4550
x = 1;
@@ -82,6 +87,7 @@ $$a \cdot \left(x_0 + \frac{b}{g}\right) + b \cdot \left(y_0 - \frac{a}{g}\right
8287
Obviously, this process can be repeated again, so all the numbers of the form:
8388
8489
$$x = x_0 + k \cdot \frac{b}{g}$$
90+
8591
$$y = y_0 - k \cdot \frac{a}{g}$$
8692
8793
are solutions of the given Diophantine equation.
@@ -109,7 +115,7 @@ Following is the code implementing this idea.
109115
Notice that we divide $a$ and $b$ at the beginning by $g$.
110116
Since the equation $a x + b y = c$ is equivalent to the equation $\frac{a}{g} x + \frac{b}{g} y = \frac{c}{g}$, we can use this one instead and have $\gcd(\frac{a}{g}, \frac{b}{g}) = 1$, which simplifies the formulas.
111117
112-
```cpp linear_diophantine_all
118+
```{.cpp file=linear_diophantine_all}
113119
void shift_solution(int & x, int & y, int a, int b, int cnt) {
114120
x += cnt * b;
115121
y -= cnt * a;
@@ -162,7 +168,7 @@ int find_all_solutions(int a, int b, int c, int minx, int maxx, int miny, int ma
162168

163169
Once we have $l_x$ and $r_x$, it is also simple to enumerate through all the solutions. Just need to iterate through $x = l_x + k \cdot \frac{b}{g}$ for all $k \ge 0$ until $x = r_x$, and find the corresponding $y$ values using the equation $a x + b y = c$.
164170

165-
## Find the solution with minimum value of $x + y$
171+
## Find the solution with minimum value of $x + y$ { data-toc-label='Find the solution with minimum value of <script type="math/tex">x + y</script>' }
166172

167173
Here, $x$ and $y$ also need to be given some restriction, otherwise, the answer may become negative infinity.
168174

@@ -171,6 +177,7 @@ The idea is similar to previous section: We find any solution of the Diophantine
171177
Finally, use the knowledge of the set of all solutions to find the minimum:
172178

173179
$$x' = x + k \cdot \frac{b}{g},$$
180+
174181
$$y' = y - k \cdot \frac{a}{g}.$$
175182

176183
Note that $x + y$ change as follows:

0 commit comments

Comments
 (0)