Подтема 6 из 6 · дополнительный урок
Вид числа по количеству делителей
Количество делителей по разложению и построение кандидатов вместо перебора огромного отрезка.
Количество делителей
Дополнительный урок — для огромных диапазонов. Когда чисел так много, что искать делители у каждого не успеть, помогает разложение: по количеству делителей видно, как выглядит число, и строят только таких кандидатов. Задачи основных подтем решаются без этого урока.
Как узнать количество делителей по разложению, не выписывая их?
Каждый делитель собирают из тех же простых множителей: двоек — от 0 до трёх штук, троек — от 0 до двух. Для 72 = 2³ · 3² это 4 · 3 = 12 вариантов. Разложим делители 72 сеткой: строка — сколько взяли двоек, столбец — сколько троек.
В общем виде: если n = p₁a₁ · p₂a₂ · … · pₖaₖ, то делителей (a₁ + 1)(a₂ + 1)…(aₖ + 1). Единица прибавляется, потому что множитель можно не брать вовсе. 360 = 2³ · 3² · 5, делителей 4 · 3 · 2 = 24. Формула считает и 1, и само число; без них делителей на 2 меньше.
Сетка заодно делит делители на чётные и нечётные. В верхней строке двоек нет — там три нечётных делителя: 1, 3, 9. В остальных строках двойка есть хотя бы одна, это девять чётных делителей.
Вид числа
Какие числа имеют ровно три делителя?
Только квадраты простых чисел, p²: 3 нельзя разложить в произведение чисел больше 1, значит, простой множитель один и стоит во второй степени. 4, 9, 25, 49, 121 — у 25 делители 1, 5, 25. Так же выводятся и другие случаи — выбери количество (p и q — разные простые):
- 2 делителя
- p
- 3 делителя
- p²
- 4 делителя
- p³ или pq4 = 4 даёт p³, 4 = 2 · 2 даёт pq: 8 = 2³ и 15 = 3 · 5
- 5 делителей
- p⁴
- 6 делителей
- p⁵ или p²q
Где тут выигрыш? Числа до 10¹² ровно с пятью делителями — это p⁴, а p⁴ ≤ 10¹² значит p ≤ 1000. Вместо триллиона чисел — простые до тысячи, их 168:
found = [p ** 4 for p in range(2, 1001) if is_prime(p)]print(len(found), found[:5])Нечётное количество
У каких чисел нечётное количество делителей?
Только у квадратов: делители идут парами, и лишь у квадрата одна пара — √n и √n — даёт один делитель. Сравни 36 и 40:
Поэтому «нечётное количество делителей» проверяют без делителей: isqrt(n) ** 2 == n — n полный квадрат.
Вид вместо перебора
Найди числа на отрезке [10⁹; 10⁹ + 2 000 000] ровно с тремя делителями и для каждого — наибольший делитель меньше самого числа. Два миллиона чисел, у каждого до 31 600 кандидатов в делители — это 6 · 10¹⁰ проверок. Как успеть?
Перебирать не числа, а простые p, у которых p² попадает на отрезок. Делители p² — 1, p и p², поэтому наибольший делитель меньше числа — это p.
low = 10**9high = 10**9 + 2_000_000for p in range(isqrt(low - 1) + 1, isqrt(high) + 1): if is_prime(p): print(p * p, p)Кандидатов p около тридцати. Нижняя граница isqrt(low - 1) + 1 — наименьшее p, у которого p² ≥ low: если low не квадрат, isqrt(low) дал бы p² меньше low.
Вид числа и маска
Числа до 10⁸ по маске 1*369 ровно с тремя делителями. Строить по маске или по виду числа?
По виду: чисел p² до 10⁸ мало — p не больше 10 000, — и у каждого проверяем только маску. По маске вышло бы 1111 кандидатов, и у каждого пришлось бы искать делители.
from fnmatch import fnmatch for p in range(2, 10**4 + 1): if is_prime(p) and fnmatch(str(p * p), '1*369'): print(p * p)Перебор p не растёт, если маска станет сложнее: он зависит только от границы.
Итого
- Количество(a₁ + 1)(a₂ + 1)…(aₖ + 1) по разложению
- 3 делителяp²
- 4 делителяp³ или p · q
- 5 делителейp⁴
- Нечётное количествотолько полные квадраты
- Огромный отрезокперебирать p, а не числа
Проверьте себя
Ответь сначала сам, потом открой ответ.
ОтветСкрыть ответ
ОтветСкрыть ответ
ОтветСкрыть ответ
ОтветСкрыть ответ
Практика
Для проверки ответов нужен JavaScript. Условия, подсказки и решения доступны ниже.
Посчитай делители 72 по разложению
Для числа 72 определи количество всех делителей, чётных делителей и нечётных делителей — по разложению, без перебора.
Введите три числа через пробел: количество всех, чётных и нечётных делителей.
Подсказка
72 = 2³ · 3². Нечётный делитель не содержит двойки, чётный содержит её хотя бы раз.
Решение
72 = 2³ · 3²: всех — 12, чётных — 9, нечётных — 3. Программа проверяет формулу перебором делителей.
Решение программой
from math import isqrt def get_divisors(n): divisors = [] for d in range(1, isqrt(n) + 1): if n % d == 0: divisors.append(d) q = n // d if q != d: divisors.append(q) return sorted(divisors) D = get_divisors(72)even = [d for d in D if d % 2 == 0]print(len(D), len(even), len(D) - len(even))Ответ: 12 9 3
Посчитай делители 1960 по разложению
Сколько натуральных делителей у числа 1960? Посчитай по разложению 1960 = 2³ · 5 · 7².
Введите количество делителей.
Подсказка
Количество делителей — произведение показателей разложения, увеличенных на единицу.
Решение
24: (3 + 1)(1 + 1)(2 + 1).
Решение программой
from math import isqrt def count_divisors(n): count = 0 for d in range(1, isqrt(n) + 1): if n % d == 0: if d * d == n: count += 1 else: count += 2 return count print(count_divisors(1960))Ответ: 24
Найди числа с пятью делителями до 100
Найди все числа от 1 до 100, имеющие ровно пять натуральных делителей. Попробуй решить двумя способами: поиском делителей и через вид числа.
Введите числа через пробел в порядке возрастания.
Подсказка
Пять — простое число, поэтому формула количества делителей оставляет только вид p⁴.
Решение
Ровно пять делителей у чисел вида p⁴: 2⁴ = 16 и 3⁴ = 81. Следующее, 5⁴ = 625, больше 100.
Решение программой
from math import isqrt def count_divisors(n): count = 0 for d in range(1, isqrt(n) + 1): if n % d == 0: if d * d == n: count += 1 else: count += 2 return count print(*[n for n in range(1, 101) if count_divisors(n) == 5])Ответ: 16 81
Найди числа с тремя делителями после 50
Найди три наименьших числа, больших 50, у которых ровно три натуральных делителя.
Введите три числа через пробел в порядке возрастания.
Подсказка
Ровно три делителя бывают только у квадратов простых чисел.
Решение
121, 169, 289 — квадраты простых 11, 13, 17. Число 81 не подходит: 81 = 3⁴, у него пять делителей.
Решение программой
from math import isqrt def count_divisors(n): count = 0 for d in range(1, isqrt(n) + 1): if n % d == 0: if d * d == n: count += 1 else: count += 2 return count found = []n = 51while len(found) < 3: if count_divisors(n) == 3: found.append(n) n += 1print(*found)Ответ: 121 169 289
Посчитай числа с нечётным числом делителей
Сколько чисел от 1 до 10 000 имеют нечётное количество натуральных делителей?
Введите количество чисел.
Подсказка
Делители образуют пары; без пары остаётся только корень квадрата.
Решение
100: это квадраты 1², 2², …, 100².
Решение программой
from math import isqrt def count_divisors(n): count = 0 for d in range(1, isqrt(n) + 1): if n % d == 0: if d * d == n: count += 1 else: count += 2 return count count = 0for n in range(1, 10001): if count_divisors(n) % 2 == 1: count += 1print(count)Ответ: 100
Найди числа вида 2ᵐ · 3ⁿ на огромном отрезке
Найди все числа N на отрезке [2·10⁸; 6·10⁸], которые можно представить в виде N = 2ᵐ · 3ⁿ, где m — чётное неотрицательное число, а n — нечётное. Выведи их в порядке возрастания.
Введите числа через пробел в порядке возрастания.
Подсказка
Перебирай показатели m и n, а не числа отрезка: степеней двойки и тройки до 6·10⁸ всего несколько десятков.
Решение
Перебираем показатели, а не числа: m — чётные от 0, n — нечётные, и оставляем произведения из отрезка. Подходят восемь чисел.
Решение программой
found = []for m in range(0, 40, 2): for k in range(1, 40, 2): N = 2**m * 3**k if 2 * 10**8 <= N <= 6 * 10**8: found.append(N)print(*sorted(found))Ответ: 201326592 229582512 254803968 322486272 408146688 452984832 516560652 573308928