Розгляньмо функцію , яка для додатного цілого числа повертає суму всіх його додатних дільників.
Якщо n = p, де — просте число, то у рівно два дільники: і . Отже
Якщо n = p^a, де — просте число і a \ge 1, то всі дільники числа мають вигляд:
Їх сума утворює геометричну прогресію, тому
Функція є мультиплікативною, тобто для будь-яких взаємно простих чисел і виконується рівність:
Нехай натуральне число має розклад на прості множники:
де p_1, p_2, ..., p_k — різні прості числа.
Тоді, використовуючи мультиплікативність і формулу для степенів простих чисел, отримуємо:
Зазначену суму можна записати також у вигляді
Приклад
Число n = 239 є простим, тобто має рівно два додатних дільники: і . За визначенням функції суми дільників отримуємо:
Розгляньмо число n = 24. Його розклад на прості множники має вигляд:
Оскільки числа 2^3 і взаємно прості, можна скористатися мультиплікативністю функції :
Обчислимо суму дільників для числа n = 24 безпосередньо. Перелічимо всі додатні дільники числа :
Складемо їх:
Зауважимо, що всі дільники можна згрупувати наступним чином:
Реалізація алгоритму
Читаємо вхідне значення .
scanf("%lld",&n);У змінній обчислюємо значення .
res = 1;У змінній перебираємо всі прості дільники числа (за умовою задачі вони не перевищують ). Для кожного такого дільника за формулою, виведеною в аналізі задачі, обчислюється внесок у суму дільників числа .
for (i = 2; i <= 1000; i++)
{
p = i;Нехай — простий дільник числа . Знайдемо найбільшу степінь , для якої i^a ділить .
while(n % i == 0)
{
n /= i;
p *= i;
}Після завершення циклу отримуємо p = i^{a+1}. Далі множимо поточне значення змінної на \frac{i^{a + 1} - 1}{i - 1}.
res *= (p - 1) / (i - 1);
}Виведемо відповідь.
printf("%lld\n",res);Java реалізація
import java.util.*;
class Main
{
public static void main(String[] args)
{
Scanner con = new Scanner(System.in);
long n = con.nextLong();
long res = 1;
for(int i = 2; i <= 1000; i++)
{
long p = i;
while(n % i == 0)
{
n /= i;
p *= i;
}
res *= (p - 1) / (i - 1);
}
System.out.println(res);
con.close();
}
}Python реалізація
Читаємо вхідне значення .
n = int(input())У змінній обчислюємо значення .
res = 1У змінній перебираємо всі прості дільники числа (за умовою задачі вони не перевищують ). Для кожного такого дільника за формулою, виведеною в аналізі задачі, обчислюється внесок у суму дільників числа .
for i in range (2,1000) :
p = iНехай — простий дільник числа . Знайдемо найбільшу степінь , для якої i^a ділить .
while(n % i == 0) :
n = n // i
p *= iПісля завершення циклу отримуємо p = i^{a+1}. Далі множимо поточне значення змінної на \frac{i^{a + 1} - 1}{i - 1}.
res *= (p - 1) // (i - 1) Виведемо відповідь.
print(res)