Skip to content

add_script updates center tags for all images #1447

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/algebra/factorization.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,9 @@ If $p$ is smaller than $\sqrt{n}$, the repetition will likely start in $O(\sqrt[
Here is a visualization of such a sequence $\{x_i \bmod p\}$ with $n = 2206637$, $p = 317$, $x_0 = 2$ and $f(x) = x^2 + 1$.
From the form of the sequence you can see very clearly why the algorithm is called Pollard's $\rho$ algorithm.

<center>![Pollard's rho visualization](pollard_rho.png)</center>
<div style="text-align: center;">
<img src="pollard_rho.png" alt="Pollard's rho visualization">
</div>

Yet, there is still an open question.
How can we exploit the properties of the sequence $\{x_i \bmod p\}$ to our advantage without even knowing the number $p$ itself?
Expand Down
4 changes: 3 additions & 1 deletion src/algebra/sieve-of-eratosthenes.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ And we continue this procedure until we have processed all numbers in the row.

In the following image you can see a visualization of the algorithm for computing all prime numbers in the range $[1; 16]$. It can be seen, that quite often we mark numbers as composite multiple times.

<center>![Sieve of Eratosthenes](sieve_eratosthenes.png)</center>
<div style="text-align: center;">
<img src="sieve_eratosthenes.png" alt="Sieve of Eratosthenes">
</div>

The idea behind is this:
A number is prime, if none of the smaller prime numbers divides it.
Expand Down
4 changes: 3 additions & 1 deletion src/data_structures/fenwick.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@ where $|$ is the bitwise OR operator.
The following image shows a possible interpretation of the Fenwick tree as tree.
The nodes of the tree show the ranges they cover.

<center>![Binary Indexed Tree](binary_indexed_tree.png)</center>
<div style="text-align: center;">
<img src="binary_indexed_tree.png" alt="Binary Indexed Tree">
</div>

## Implementation

Expand Down
16 changes: 12 additions & 4 deletions src/geometry/basic-geometry.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,9 @@ The dot (or scalar) product $\mathbf a \cdot \mathbf b$ for vectors $\mathbf a$
Geometrically it is product of the length of the first vector by the length of the projection of the second vector onto the first one.
As you may see from the image below this projection is nothing but $|\mathbf a| \cos \theta$ where $\theta$ is the angle between $\mathbf a$ and $\mathbf b$. Thus $\mathbf a\cdot \mathbf b = |\mathbf a| \cos \theta \cdot |\mathbf b|$.

<center>![](https://upload.wikimedia.org/wikipedia/commons/thumb/3/3e/Dot_Product.svg/300px-Dot_Product.svg.png)</center>
<div style="text-align: center;">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/3/3e/Dot_Product.svg/300px-Dot_Product.svg.png" alt="">
</div>

The dot product holds some notable properties:

Expand Down Expand Up @@ -181,7 +183,9 @@ To see the next important property we should take a look at the set of points $\
You can see that this set of points is exactly the set of points for which the projection onto $\mathbf a$ is the point $C \cdot \dfrac{\mathbf a}{|\mathbf a|}$ and they form a hyperplane orthogonal to $\mathbf a$.
You can see the vector $\mathbf a$ alongside with several such vectors having same dot product with it in 2D on the picture below:

<center>![Vectors having same dot product with a](https://i.imgur.com/eyO7St4.png)</center>
<div style="text-align: center;">
<img src="https://i.imgur.com/eyO7St4.png" alt="Vectors having same dot product with a">
</div>

In 2D these vectors will form a line, in 3D they will form a plane.
Note that this result allows us to define a line in 2D as $\mathbf r\cdot \mathbf n=C$ or $(\mathbf r - \mathbf r_0)\cdot \mathbf n=0$ where $\mathbf n$ is vector orthogonal to the line and $\mathbf r_0$ is any vector already present on the line and $C = \mathbf r_0\cdot \mathbf n$.
Expand All @@ -192,14 +196,18 @@ In the same manner a plane can be defined in 3D.
### Definition

Assume you have three vectors $\mathbf a$, $\mathbf b$ and $\mathbf c$ in 3D space joined in a parallelepiped as in the picture below:
<center>![Three vectors](https://upload.wikimedia.org/wikipedia/commons/thumb/3/3e/Parallelepiped_volume.svg/240px-Parallelepiped_volume.svg.png)</center>
<div style="text-align: center;">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/3/3e/Parallelepiped_volume.svg/240px-Parallelepiped_volume.svg.png" alt="Three vectors">
</div>

How would you calculate its volume?
From school we know that we should multiply the area of the base with the height, which is projection of $\mathbf a$ onto direction orthogonal to base.
That means that if we define $\mathbf b \times \mathbf c$ as the vector which is orthogonal to both $\mathbf b$ and $\mathbf c$ and which length is equal to the area of the parallelogram formed by $\mathbf b$ and $\mathbf c$ then $|\mathbf a\cdot (\mathbf b\times\mathbf c)|$ will be equal to the volume of the parallelepiped.
For integrity we will say that $\mathbf b\times \mathbf c$ will be always directed in such way that the rotation from the vector $\mathbf b$ to the vector $\mathbf c$ from the point of $\mathbf b\times \mathbf c$ is always counter-clockwise (see the picture below).

<center>![cross product](https://upload.wikimedia.org/wikipedia/commons/thumb/b/b0/Cross_product_vector.svg/250px-Cross_product_vector.svg.png)</center>
<div style="text-align: center;">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b0/Cross_product_vector.svg/250px-Cross_product_vector.svg.png" alt="cross product">
</div>

This defines the cross (or vector) product $\mathbf b\times \mathbf c$ of the vectors $\mathbf b$ and $\mathbf c$ and the triple product $\mathbf a\cdot(\mathbf b\times \mathbf c)$ of the vectors $\mathbf a$, $\mathbf b$ and $\mathbf c$.

Expand Down
8 changes: 6 additions & 2 deletions src/geometry/convex_hull_trick.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ The idea of this approach is to maintain a lower convex hull of linear functions
Actually it would be a bit more convenient to consider them not as linear functions, but as points $(k;b)$ on the plane such that we will have to find the point which has the least dot product with a given point $(x;1)$, that is, for this point $kx+b$ is minimized which is the same as initial problem.
Such minimum will necessarily be on lower convex envelope of these points as can be seen below:

<center> ![lower convex hull](convex_hull_trick.png) </center>
<div style="text-align: center;">
<img src="convex_hull_trick.png" alt="lower convex hull">
</div>

One has to keep points on the convex hull and normal vectors of the hull's edges.
When you have a $(x;1)$ query you'll have to find the normal vector closest to it in terms of angles between them, then the optimum linear function will correspond to one of its endpoints.
Expand Down Expand Up @@ -90,7 +92,9 @@ Assume we're in some vertex corresponding to half-segment $[l,r)$ and the functi

Here is the illustration of what is going on in the vertex when we add new function:

<center>![Li Chao Tree vertex](li_chao_vertex.png)</center>
<div style="text-align: center;">
<img src="li_chao_vertex.png" alt="Li Chao Tree vertex">
</div>

Let's go to implementation now. Once again we will use complex numbers to keep linear functions.

Expand Down
4 changes: 3 additions & 1 deletion src/geometry/delaunay.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ Because of the duality, we only need a fast algorithm to compute only one of $V$
## Quad-edge data structure

During the algorithm $D$ will be stored inside the quad-edge data structure. This structure is described in the picture:
<center>![Quad-Edge](quad-edge.png)</center>
<div style="text-align: center;">
<img src="quad-edge.png" alt="Quad-Edge">
</div>

In the algorithm we will use the following functions on edges:

Expand Down
12 changes: 9 additions & 3 deletions src/geometry/intersecting_segments.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,24 @@ The naive solution algorithm is to iterate over all pairs of segments in $O(n^2)
Let's draw a vertical line $x = -\infty$ mentally and start moving this line to the right.
In the course of its movement, this line will meet with segments, and at each time a segment intersect with our line it intersects in exactly one point (we will assume that there are no vertical segments).

<center>![sweep line and line segment intersection](sweep_line_1.png)</center>
<div style="text-align: center;">
<img src="sweep_line_1.png" alt="sweep line and line segment intersection">
</div>

Thus, for each segment, at some point in time, its point will appear on the sweep line, then with the movement of the line, this point will move, and finally, at some point, the segment will disappear from the line.

We are interested in the **relative order of the segments** along the vertical.
Namely, we will store a list of segments crossing the sweep line at a given time, where the segments will be sorted by their $y$-coordinate on the sweep line.

<center>![relative order of the segments across sweep line](sweep_line_2.png)</center>
<div style="text-align: center;">
<img src="sweep_line_2.png" alt="relative order of the segments across sweep line">
</div>

This order is interesting because intersecting segments will have the same $y$-coordinate at least at one time:

<center>![intersection point having same y-coordinate](sweep_line_3.png)</center>
<div style="text-align: center;">
<img src="sweep_line_3.png" alt="intersection point having same y-coordinate">
</div>

We formulate key statements:

Expand Down
8 changes: 6 additions & 2 deletions src/geometry/lattice-points.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ We have two cases:
This amount is the same as the number of points such that $0 < y \leq (k - \lfloor k \rfloor) \cdot x + (b - \lfloor b \rfloor)$.
So we reduced our problem to $k'= k - \lfloor k \rfloor$, $b' = b - \lfloor b \rfloor$ and both $k'$ and $b'$ less than $1$ now.
Here is a picture, we just summed up blue points and subtracted the blue linear function from the black one to reduce problem to smaller values for $k$ and $b$:
<center>![Subtracting floored linear function](lattice.png)</center>
<div style="text-align: center;">
<img src="lattice.png" alt="Subtracting floored linear function">
</div>

- $k < 1$ and $b < 1$.

Expand All @@ -51,7 +53,9 @@ We have two cases:

which returns us back to the case $k>1$.
You can see new reference point $O'$ and axes $X'$ and $Y'$ in the picture below:
<center>![New reference and axes](mirror.png)</center>
<div style="text-align: center;">
<img src="mirror.png" alt="New reference and axes">
</div>
As you see, in new reference system linear function will have coefficient $\tfrac 1 k$ and its zero will be in the point $\lfloor k\cdot n + b \rfloor-(k\cdot n+b)$ which makes formula above correct.

## Complexity analysis
Expand Down
8 changes: 6 additions & 2 deletions src/geometry/manhattan-distance.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ $$d(p,q) = |x_p - x_q| + |y_p - y_q|$$

Defined this way, the distance corresponds to the so-called [Manhattan (taxicab) geometry](https://en.wikipedia.org/wiki/Taxicab_geometry), in which the points are considered intersections in a well designed city, like Manhattan, where you can only move on the streets horizontally or vertically, as shown in the image below:

<center>![Manhattan Distance](https://upload.wikimedia.org/wikipedia/commons/thumb/0/08/Manhattan_distance.svg/220px-Manhattan_distance.svg.png)</center>
<div style="text-align: center;">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/0/08/Manhattan_distance.svg/220px-Manhattan_distance.svg.png" alt="Manhattan Distance">
</div>

This images show some of the smallest paths from one black point to the other, all of them with length $12$.

Expand Down Expand Up @@ -77,7 +79,9 @@ Also, we may realize that $\alpha$ is a [spiral similarity](https://en.wikipedia

Here's an image to help visualizing the transformation:

<center>![Chebyshev transformation](chebyshev-transformation.png)</center>
<div style="text-align: center;">
<img src="chebyshev-transformation.png" alt="Chebyshev transformation">
</div>

## Manhattan Minimum Spanning Tree

Expand Down
4 changes: 3 additions & 1 deletion src/geometry/minkowski.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ We repeat the following steps while $i < |P|$ or $j < |Q|$.

Here is a nice visualization, which may help you understand what is going on.

<center>![Visual](minkowski.gif)</center>
<div style="text-align: center;">
<img src="minkowski.gif" alt="Visual">
</div>

## Distance between two polygons
One of the most common applications of Minkowski sum is computing the distance between two convex polygons (or simply checking whether they intersect).
Expand Down
8 changes: 6 additions & 2 deletions src/geometry/planar.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ It's quite clear that the complexity of the algorithm is $O(m \log m)$ because o

At the first glance it may seem that finding faces of a disconnected graph is not much harder because we can run the same algorithm for each connected component. However, the components may be drawn in a nested way, forming **holes** (see the image below). In this case the inner face of some component becomes the outer face of some other components and has a complex disconnected border. Dealing with such cases is quite hard, one possible approach is to identify nested components with [point location](point-location.md) algorithms.

<center>![Planar graph with holes](planar_hole.png)</center>
<div style="text-align: center;">
<img src="planar_hole.png" alt="Planar graph with holes">
</div>

## Implementation
The following implementation returns a vector of vertices for each face, outer face goes first.
Expand Down Expand Up @@ -147,7 +149,9 @@ std::vector<std::vector<size_t>> find_faces(std::vector<Point> vertices, std::ve

Sometimes you are not given a graph explicitly, but rather as a set of line segments on a plane, and the actual graph is formed by intersecting those segments, as shown in the picture below. In this case you have to build the graph manually. The easiest way to do so is as follows. Fix a segment and intersect it with all other segments. Then sort all intersection points together with the two endpoints of the segment lexicographically and add them to the graph as vertices. Also link each two adjacent vertices in lexicographical order by an edge. After doing this procedure for all edges we will obtain the graph. Of course, we should ensure that two equal intersection points will always correspond to the same vertex. The easiest way to do this is to store the points in a map by their coordinates, regarding points whose coordinates differ by a small number (say, less than $10^{-9}$) as equal. This algorithm works in $O(n^2 \log n)$.

<center>![Implicitly defined graph](planar_implicit.png)</center>
<div style="text-align: center;">
<img src="planar_implicit.png" alt="Implicitly defined graph">
</div>

## Implementation
```{.cpp file=planar_implicit}
Expand Down
8 changes: 6 additions & 2 deletions src/geometry/point-location.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ This problem may arise when you need to locate some points in a Voronoi diagram
Firstly, for each query point $p\ (x_0, y_0)$ we want to find such an edge that if the point belongs to any edge, the point lies on the edge we found, otherwise this edge must intersect the line $x = x_0$ at some unique point $(x_0, y)$ where $y < y_0$ and this $y$ is maximum among all such edges.
The following image shows both cases.

<center>![Image of Goal](point_location_goal.png)</center>
<div style="text-align: center;">
<img src="point_location_goal.png" alt="Image of Goal">
</div>

We will solve this problem offline using the sweep line algorithm. Let's iterate over x-coordinates of query points and edges' endpoints in increasing order and keep a set of edges $s$. For each x-coordinate we will add some events beforehand.

Expand All @@ -27,7 +29,9 @@ Finally, for each query point we will add one _get_ event for its x-coordinate.
For each x-coordinate we will sort the events by their types in order (_vertical_, _get_, _remove_, _add_).
The following image shows all events in sorted order for each x-coordinate.

<center>![Image of Events](point_location_events.png)</center>
<div style="text-align: center;">
<img src="point_location_events.png" alt="Image of Events">
</div>

We will keep two sets during the sweep-line process.
A set $t$ for all non-vertical edges, and one set $vert$ especially for the vertical ones.
Expand Down
4 changes: 3 additions & 1 deletion src/geometry/tangents-to-two-circles.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ The described algorithm will also work in the case when one (or both) circles de
## The number of common tangents
The number of common tangents to two circles can be **0,1,2,3,4** and **infinite**.
Look at the images for different cases.
<center>!["Different cases of tangents common to two circles"](tangents-to-two-circles.png)</center>
<div style="text-align: center;">
<img src="tangents-to-two-circles.png" alt=""Different cases of tangents common to two circles"">
</div>

Here, we won't be considering **degenerate** cases, i.e *when the circles coincide (in this case they have infinitely many common tangents), or one circle lies inside the other (in this case they have no common tangents, or if the circles are tangent, there is one common tangent).*

Expand Down
4 changes: 3 additions & 1 deletion src/geometry/vertical_decomposition.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ For simplicity we will show how to do this for an upper segment, the algorithm f

Here is a graphic representation of the three cases.

<center>![Visual](triangle_union.png)</center>
<div style="text-align: center;">
<img src="triangle_union.png" alt="Visual">
</div>

Finally we should remark on processing all the additions of $1$ or $-1$ on all stripes in $[x_1, x_2]$. For each addition of $w$ on $[x_1, x_2]$ we can create events $(x_1, w),\ (x_2, -w)$
and process all these events with a sweep line.
Expand Down
8 changes: 6 additions & 2 deletions src/graph/2SAT.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ b \Rightarrow a & \lnot b \Rightarrow \lnot a & b \Rightarrow \lnot a & c \Right

You can see the implication graph in the following image:

<center>!["Implication Graph of 2-SAT example"](2SAT.png)</center>
<div style="text-align: center;">
<img src="2SAT.png" alt=""Implication Graph of 2-SAT example"">
</div>

It is worth paying attention to the property of the implication graph:
if there is an edge $a \Rightarrow b$, then there also is an edge $\lnot b \Rightarrow \lnot a$.
Expand All @@ -59,7 +61,9 @@ The following image shows all strongly connected components for the example.
As we can check easily, neither of the four components contain a vertex $x$ and its negation $\lnot x$, therefore the example has a solution.
We will learn in the next paragraphs how to compute a valid assignment, but just for demonstration purposes the solution $a = \text{false}$, $b = \text{false}$, $c = \text{false}$ is given.

<center>!["Strongly Connected Components of the 2-SAT example"](2SAT_SCC.png)</center>
<div style="text-align: center;">
<img src="2SAT_SCC.png" alt=""Strongly Connected Components of the 2-SAT example"">
</div>

Now we construct the algorithm for finding the solution of the 2-SAT problem on the assumption that the solution exists.

Expand Down
Loading