Найдите все натуральные числа, принадлежащие отрезку [
;
], у которых ровно
различных четных делителя. Общее количество делителей может быть любым. В ответе укажите количество данных чисел.
По основной теореме арифметики (ОТА) каждое натуральное число, большее 1, можно разложить на простые множители. То есть некоторое натуральное число можно разложить в следующий вид:
Здесь – некоторое простое число, а
– натуральный показатель степени. В таком случае число обязательно имеет
делителей (каждое простое число можно брать от 0 до
раз, где
).
В данной задаче необходимо, чтобы у числа было ровно чётных делителей. Значит в разложении числа должно участвовать простое число
.
Пусть число имеет следующий вид:
Выпишем количество делителей числа:
Выпишем количество делителей числа, не содержащих степень числа 2, то есть не являющихся чётными:
Из общего количества делителей вычтем количество делителей, не являющихся чётными, и получим количество чётных делителей:
Обозначим произведение всех за
. Так как количество по условию должно быть равно
, то
. Так как число
– простое, то либо
и
, либо
и
.
В первом случае это число , так как
означает, что других простых чисел в разложении числа нет.
Во втором случае произведение всех равно
, а значит только один множитель должен быть равен
(так как
– простое число). Отсюда некоторое
. Поэтому число будет иметь вид
.
В общем случае это можно представить, как где
– любое простое число (включая число
, что обобщает эти два случая).
Таким образом, нужно будет перебрать простые числа так, чтобы получить все возможные числа вида из отрезка
.
def is_prime(n): # Функция проверки на простое число
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0: # Если нашли нетривиальный делитель
return False # То число не простое, возвращаем False
return n > 1 # Если число равно 1, то оно непростое, и будет возвращено False, а иначе True
# Нужно перебрать все числа вида x = 2 * p**2, где p - простое число
ans = 0 # Счётчик для ответа
# Находим максимально возможное p для отрезка
p_max = int(333_333_333 ** (1 / 2))
# Перебираем простые числа от 2 до максимально возможного
for p in range(2, p_max + 1):
if is_prime(p): # Если число p - простое
# То проверяем, что итоговое число будет принадлежать отрезку
if 33_333_333 <= 2 * p ** 2 <= 333_333_333:
ans += 1
print(ans)