From b58b12aa928e9a0f65ed5ddec42b11185fe77168 Mon Sep 17 00:00:00 2001 From: Dmitrii <36790425+dimaush@users.noreply.github.com> Date: Mon, 3 Mar 2025 18:56:02 +0300 Subject: [PATCH] Some minor corrections and improvements --- .../russian/cs/factorization/eratosthenes.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/content/russian/cs/factorization/eratosthenes.md b/content/russian/cs/factorization/eratosthenes.md index acf47749..1763286b 100644 --- a/content/russian/cs/factorization/eratosthenes.md +++ b/content/russian/cs/factorization/eratosthenes.md @@ -10,7 +10,7 @@ published: true **Решето Эратосфена** (англ. *sieve of Eratosthenes*) — алгоритм нахождения всех простых чисел от $1$ до $n$. -Основная идея соответствует названию алгоритма: запишем ряд чисел $1, 2,\ldots, n$, а затем будем вычеркивать +Основная идея соответствует названию алгоритма: запишем ряд чисел $1, 2,\ldots, n$, а затем будем вычёркивать: - сначала числа, делящиеся на $2$, кроме самого числа $2$, - потом числа, делящиеся на $3$, кроме самого числа $3$, @@ -24,7 +24,8 @@ published: true ```c++ vector sieve(int n) { vector is_prime(n + 1, true); - for (int i = 2; i <= n; i++) + is_prime[0] = false, is_prime[1] = false; + for (int i = 2; i <= n; ++i) if (is_prime[i]) for (int j = 2 * i; j <= n; j += i) is_prime[j] = false; @@ -44,14 +45,14 @@ $$ \sum_k \frac{n}{k} = \frac{n}{2} + \frac{n}{3} + \frac{n}{4} + \ldots + \frac{n}{n} = O(n \log n) $$ -Здесь мы воспользовались асимптотикой [гармонического ряда](https://ru.wikipedia.org/wiki/%D0%93%D0%B0%D1%80%D0%BC%D0%BE%D0%BD%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D1%80%D1%8F%D0%B4). +Здесь мы воспользовались асимптотикой [гармонического ряда](https://ru.wikipedia.org/wiki/Гармонический_ряд). У исходного алгоритма асимптотика должна быть ещё лучше. Чтобы найти её точнее, нам понадобятся два факта про простые числа: -1. Простых чисел от $1$ до $n$ примерно $\frac{n}{\ln n}$ . -2. Простые числа распределены без больших «разрывов» и «скоплений», то есть $k$-тое простое число примерно равно $k \ln k$. +1. простых чисел от $1$ до $n$ примерно $\frac{n}{\ln n}$; +2. простые числа распределены без больших «разрывов» и «скоплений», то есть $k$-ое простое число примерно равно $k \ln k$. -Мы можем упрощённо считать, что число $k$ является простым с «вероятностью» $\frac{1}{\ln n}$. Тогда, время работы алгоритма можно более точнее оценить как +Можно упрощённо считать, что число $n$ является простым с «вероятностью» $\frac{1}{\ln n}$. Тогда время работы алгоритма можно более точно оценить как $$ \sum_k \frac{1}{\ln k} \frac{n}{k} @@ -66,13 +67,13 @@ $$ Основная проблема решета Эратосфена состоит в том, что некоторые числа мы будем помечать как составные несколько раз — столько, сколько у них различных простых делителей. Чтобы достичь линейного времени работы, нам нужно придумать способ, как рассматривать все составные числа ровно один раз. -Обозначим за $d(k)$ минимальный простой делитель числа $k$ и заметим следующий факт: у составного числа $k$ есть единственное представление $k = d(k) \cdot r$, и при этом у числа $r$ нет простых делителей меньше $d(k)$. +Обозначим за $d(k)$ минимальный простой делитель числа $k$ и заметим следующий факт: любое составное число $k$ можно представить в виде $k = d(k) \cdot r$, причём у числа $r$ все простые нет делители не меньше $d(k)$. -Идея оптимизации состоит в том, чтобы перебирать этот $r$, и для каждого перебирать только нужные множители — а именно, все от $2$ до $d(r)$ включительно. +Идея оптимизации состоит в том, чтобы перебирать это $r$, и для каждого перебирать только нужные множители — а именно, все от $2$ до $d(r)$ включительно. ### Алгоритм -Немного обобщим задачу — теперь мы хотим посчитать для каждого числа $k$ на отрезке $[2, n]$ его минимальный простой делитель $d_k$, а не только определить его простоту. +Немного обобщим задачу: теперь мы хотим для каждого числа $k$ на отрезке $[2, n]$ не только определить, простое ли оно, но и найти его наименьший простой делитель $d(k)$. Изначально массив $d$ заполним нулями, что означает, что все числа предполагаются простыми. В ходе работы алгоритма этот массив будет постепенно заполняться. Помимо этого, будем поддерживать список $p$ всех найденных на текущий момент простых чисел.