Проверка простоты – это задача установления, имеет ли натуральное число n ≥ 2 нетривиальные делители. Формально, число n простое, если множества делителей D(n) = { d ∈ ℕ : d | n } содержат ровно два элемента – 1 и n. В вычислительном плане проверка простоты – фундаментальная процедура для криптографии, комбинаторики, теории чисел и олимпиадного/экзаменационного программирования. Для ЕГЭ по информатике эта тема напрямую связывает арифметику остатков, анализ алгоритмов, циклы и ветвления, работу с массивами (решето), а также логические доказательства корректности (инварианты и границы перебора).
Ниже представлены: строгая формализация, правила корректности и безопасной реализации, классификация алгоритмов (детерминированные, вероятностные, решёта), оптимизационные приёмы (ограничение диапазона, колёса делителей, ускоренная модульная степень), мини-шпаргалка формул, типичные ошибки и 5 упражнений в стиле ЕГЭ с подробными решениями.
Определения и эквивалентности
Число n ≥ 2 простое ⇔ не существует d такое, что 1 < d < n и d | n. Эквивалентная и практически важная формулировка:
n – составное ⇔ ∃ d : 2 ≤ d ≤ ⌊√n⌋ и d | n.
Отсюда минимально корректный алгоритм: достаточно проверять делители до ⌊√n⌋. Доказательство: если n = ab и a > √n, тогда b < √n.
Теорема Ферма и предикаты простоты
Если p – простое и a – целое, взаимно простое с p, то выполняется
a^{p-1} ≡ 1 (mod p).
Поэтому для простого p и любого 1 < a < p: a^{p-1} mod p = 1. Обратное неверно (есть числа Кармайкла), но это даёт вероятностные тесты.
Представление n-1 = 2^s · d
Для нечётного n > 2 удобно разложить n-1 на степенную двойку:
n - 1 = 2^s · d, d – нечётное.
Это ядро теста Миллера–Рабина (MR): проверка цепочки квадратов a^d, a^{2d}, a^{4d}, …, a^{2^{s-1}d} (mod n).
Детерминированные переборные методы
Тривиальная проверка делителей: тестировать d = 2..⌊√n⌋. Сложность O(√n).
С пропуском чётных: проверить 2, потом d = 3,5,7,… – вдвое быстрее.
Колесо делителей (wheel factorization): тестировать только d, взаимно простые с первым набором малых простых (напр. колёсо по 2·3·5 = 30 → остатки 1,7,11,13,17,19,23,29).
Детерминированные MR для ограниченных диапазонов: для 32-/64-битных чисел известны конечные наборы оснований, делающие MR детерминированным (см. §4.4).
Вероятностные тесты
Ферма (простые свидетели): случайный a из [2..n-2], проверить a^{n-1} ≡ 1 (mod n). Быстр, но уязвим к числам Кармайкла.
Миллер–Рабин (strong pseudoprime test): значительно надёжнее; вероятность ложноположительного результата не более 1/4 на случайное основание (на практике сильно меньше). Для фиксированного набора оснований ≈ детерминирован для машинных слов.
Решёта (массовая простота на диапазоне)
Решето Эратосфена: O(n log log n) времени, O(n) памяти; порождает все простые ≤ n.
Сегментированное решето: экономит память, обрабатывая отрезки [L; R] с базовыми простыми ≤ √R.
Линейное решето (Эратосфен–Эйлер): выдаёт простые и минимальные простые делители за O(n) амортизированно.
Границы перебора: никогда не тестируйте делители свыше ⌊√n⌋.
Быстрые отсеки: отдельная обработка n < 2, n = 2, n чётное.
Модульная степень: реализуйте бинарное возведение в степень:
pow_mod(a, e, m):
res := 1; x := a mod m
while e > 0:
if e & 1 = 1: res := (res · x) mod m
x := (x · x) mod m
e := e >> 1
return res
Безопасность умножения: для языков с переполнением используйте 128-битные расширения, монтгомери-умножение или «умножение через сложение по модулю». В Python больших целых достаточно.
MR-инварианты: если для основания a не выполнено ни a^d ≡ 1 (mod n), ни a^{2^r d} ≡ -1 (mod n) для некоторого 0 ≤ r < s, то n – составное.
Тест Ферма используйте только как фильтр перед MR/перебором.
Решёта: помните про начальную маркировку с p^2 и шаг +p.
Повторное тестирование: в вероятностных тестах используйте несколько независимых оснований; ошибки падают геометрически.
Композитный отбор: проверка делимости на малые простые до 1–2 тысяч ускоряет MR.
Идемпотентность кода: функция is_prime(n) не должна иметь побочных эффектов (нужно для безопасного переиспользования в задачах ЕГЭ).

Проверка делителей до √n (с «колесом» 2·3·5)
function is_prime_trial(n):
if n < 2: return false
for p in [2,3,5]:
if n = p: return true
if n % p = 0: return false
# шаблон остатков по 30: 1,7,11,13,17,19,23,29
i := 7; step := [4,2,4,2,4,6,2,6] # циклически
k := 0
while i*i ≤ n:
if n % i = 0: return false
i := i + step[k]; k := (k + 1) mod 8
return true
Сложность: O(√n / log log n) эмпирически быстрее простой нечётной сетки.
Быстрое возведение в степень по модулю (бинарный метод)
function pow_mod(a, e, m):
a := a % m
res := 1
while e > 0:
if (e & 1) = 1:
res := (res * a) % m
a := (a * a) % m
e := e >> 1
return res
Сложность: O(log e) умножений по модулю.
Миллер–Рабин (одно основание)
function miller_rabin_single(n, a):
if n % a = 0: return n = a
d := n - 1; s := 0
while (d & 1) = 0:
d := d >> 1
s := s + 1
x := pow_mod(a, d, n)
if x = 1 or x = n - 1: return true
for r in 1 .. s-1:
x := (x * x) % n
if x = n - 1: return true
return false
Составность при false – доказана; true – «вероятно простое» (или простое).
Практический детерминизм для 32/64-бит
Для 32-битных n < 2^32 достаточно оснований {2, 7, 61}.
Для 64-битных n < 2^64 используются небольшие фиксированные наборы оснований (например, {2, 3, 5, 7, 11, 13, 17} или короче в версиях из литературы). На практике этого достаточно, чтобы MR был детерминированным для машинных целых.
Решето Эратосфена (базовый)
function sieve(n):
is_prime := array[0..n] of true
is_prime[0] := false; is_prime[1] := false
for p in 2 .. ⌊√n⌋:
if is_prime[p]:
for x in p*p .. n step p:
is_prime[x] := false
return is_prime
Память O(n). Для больших диапазонов – сегментированное решето: храним простые ≤ √R, помечаем кратные в текущем сегменте [L; R].
Граница перебора:
n составное ⇒ ∃ d : 2 ≤ d ≤ ⌊√n⌋, d | n.
Ферма:
a^{p-1} ≡ 1 (mod p), если gcd(a, p) = 1 и p – простое.
Разложение n − 1:
n − 1 = 2^s · d, d нечётное → цепочка квадратов в MR.
Сложность:
Trial division – O(√n)
Sieve – O(n log log n)
Pow_mod – O(log n)
MR (k основ.) – O(k log^3 n) при «наивном» умножении; на практике быстрее.
Детерминированные основания (практика):
n < 2^32 → a ∈ {2,7,61} достаточно
n < 2^64 → a ∈ {2,3,5,7,11,13,17} (один из безопасных наборов)
Упражнение 1. Граница √n и число проверок
Условие. Сколько делителей максимум проверит алгоритм перебора делителей (только нечётные после проверки 2) для числа n = 10^10 + 3? Дайте точную формулу и численную оценку.
Решение. Проверяем d = 3,5,7,…, ⌊√n⌋.
⌊√(10^10 + 3)⌋ = ⌊100000√(1 + 3·10^{-10})⌋ = 100000
Чётные пропущены, значит количество кандидатов:
count = ⌈(100000 - 1)/2⌉ = 49999
Плюс проверка на делимость на 2 = 1 операция.
Ответ. ~50 тысяч делителей (точно 49 999 нечётных + проверка на 2).
Упражнение 2. Быстрая степень по модулю
Условие. Вычислите a^{e} mod m для a = 7, e = 560, m = 561. Объясните, почему в тесте Ферма ответ «1» не означает простоту m.
Решение. 561 = 3·11·17 – число Кармайкла, для всех gcd(a,561)=1 выполняется a^{560} ≡ 1 (mod 561). Следовательно,
7^{560} mod 561 = 1
Тем не менее 561 составное (разложение выше).
Вывод. Тест Ферма даёт ложноположительные ответы на числах Кармайкла; нужен MR.
Упражнение 3. Один раунд Миллера–Рабина
Условие. Проверьте число n = 341 (известно: 341 = 11·31) одним раундом MR с основанием a = 2.
Решение.
Упражнение 4. Решето на диапазоне и количество пометок
Условие. В базовом решете до n = 100 сколько присваиваний is_prime[x] := false произойдёт при внешнем цикле p? Ответ дайте как сумму по всем простым p ≤ 10 (поскольку ⌊√100⌋ = 10).
Решение. Пометки идут от p^2 до 100 шагом p. Число пометок для данного p:
cnt(p) = ⌊(100 - p^2)/p⌋ + 1, если p^2 ≤ 100; иначе 0.
Простые ≤ 10: 2,3,5,7.
Упражнение 5. Сравнение сложностей: перебор vs MR
Условие. Оцените, при каких порядках величин n выгодно заменить перебор делителей на MR с 3 основаниями, если умножение по модулю выполняется за O(1) (условно, за счёт больших типов), а стоимость одной проверки делителя – O(1). Дайте асимптотическое сравнение.
Решение.
Перебор: T_trial(n) ≈ c₁ · √n.
MR: один раунд – O(log n) умножений; три раунда – T_MR(n) ≈ c₂ · 3 log n.
Сравниваем √n и log n: асимптотически
√n ≫ log n (при n → ∞)
т.е. MR выгоден уже при умеренных n (на практике – начиная с n в несколько тысяч/десятков тысяч и выше, в зависимости от констант, языка и железа).
Ответ. Асимптотически MR предпочтительнее; практический порог – «тысячи+».
Алгоритмы проверки простоты опираются на чёткие математические инварианты (граница √n, малые теоремы о модулярной арифметике) и аккуратную инженерную реализацию (быстрая модульная степень, безопасное умножение, корректная цепочка MR). Для единичных чисел и малых диапазонов достаточно оптимизированного перебора; для больших
значений – выигрывают вероятностные тесты с детерминированными наборами оснований. Для ЕГЭ эти подходы тренируют аналитику сложности, владение циклами и условиями, уверенную работу с остатками и массивами, а также корректное оформление кода и доказательств.