Степан і пари#4283

Степан і пари (Розбір)

Зафіксуємо (наприклад j = 12) і знайдемо кількість таких , що i = НСД(i, 12). Знайдемо значення , що задовольняють цій рівності. Ними будуть i = 1, 2, 3, 4, 6, 12. Тобто будь-яке , яке є дільником , задовольняє рівність i = НСД(i, 12).

Кількість таких , для яких i = НСД(i, j), дорівнює кількості дільників числа . Оскільки 1 \le j \le n, то залишається знайти кількість усіх дільників чисел від до . Тобто слід знайти суму

d(1) + d(2) + ... + d(n)

Оскільки обчислення вимагає факторизації числа , то безпосереднє обчислення вказаної суми потребуватиме часу .

Погляньмо на суму дільників по-іншому. Серед дільників чисел від до одиниця зустрічатиметься \lfloor{n \over 1}\rfloor разів, двійка \lfloor{n \over 2}\rfloor разів і так далі (дільник зустрічатиметься \lfloor{n \over i}\rfloor разів). Кількість шуканих пар цілих чисел дорівнює

\sum_{i=1}^n \left\lfloor \frac{n}{i} \right\rfloor

Вказану суму можна знайти за час .

Приклад

При n = 6 маємо наступні пари:

Кількість пар дорівнює

6 / 1 + 6 / 2 + 6 / 3 + 6 / 4 + 6 / 5 + 6 / 6 = \\ = 6 + 3 + 2 + 1 + 1 + 1 = 14

Реалізація алгоритму

Читаємо значення .

scanf("%d",&n);

Обчислюємо відповідь за формулою і виводимо її.

s = 0;
for (i = 1; i <= n; i++)
  s += n / i;
printf("%d\n",s);

Java реалізація

import java.util.*;

class Main
{
  public static void main(String[] args)
  {
    Scanner con = new Scanner(System.in);
    int n = con.nextInt();
    int s = 0;
    for(int i = 1; i <= n; i++)
      s += n / i;
    System.out.println(s);
    con.close();
  }
}

Python реалізація

Читаємо значення .

n = int(input())

Обчислюємо відповідь за формулою і виводимо її.

s = 0
for i in range(1,n+1):
  s += n // i
print(s)