Проблема Лонгге#1128

Проблема Лонгге (Розбір)

Теорема. Якщо функція мультиплікативна, то сумарна функція

S_f(n) = \sum_{d \mid n} f(d)

також мультиплікативна.

► Нехай x, y \in N, причому і взаємно прості.

Нехай x_1, x_2, ..., x_k — всі дільники , а y_1, y_2, ..., y_m — всі дільники .

Оскільки і взаємно прості, будь-який дільник x_i взаємно простий з будь-яким дільником y_j. Тому НСД(x_i, y_j) = 1. Це означає, що добуток x_i \cdot y_j є дільником числа x \cdot y.

Більше того, кожен добуток x_i \cdot y_j дає окремий дільник числа x \cdot y, і таким способом ми отримуємо всі дільники числа x \cdot y. Отже, суму за всіма дільниками числа x \cdot y можна подати як подвійну суму за всіма парами дільників x_i та y_j. Тоді

S_f(x) \cdot S_f(y) = \sum_{i=1}^{k} f(x_i) \cdot \sum_{j=1}^{m} f(y_j) = \sum_{i,j} f(x_i)f(y_j) = \sum_{i,j} f(x_i y_j) = S_f(xy)

Наслідок. Розглянемо функцію f(n) = НСД(n, c), де — константа. Покажемо, що ця функція є мультиплікативною.

Якщо і взаємно прості, то

f(x \cdot y) = НСД(x \cdot y, c) = НСД(x, c) \cdot НСД(y, c) = f(x) \cdot f(y)

Отже функція f(n) = НСД(n, c) є мультиплікативною.

Приклад. Обчислимо використовуючи властивість мультиплікативності.

НСД(36, 90) = НСД(4 \cdot 9, 90) = НСД(4, 90) \cdot НСД(9, 90) = 2 \cdot 9 = 18

Тепер розглянемо її сумарну функцію:

g(n) = \sum_{i=1}^{n} \gcd(i,n)

Із попередньої теореми ми знаємо, що сумарна функція мультиплікативної функції також є мультиплікативною. Отже, функція теж мультиплікативна.

Якщо розкласти на степені простих чисел n = p_1^{a_1} p_2^{a_2}...p_k^{a_k}, то

g(n) = g(p_1^{a_1} p_2^{a_2}...p_k^{a_k}) = g(p_1^{a_1}) \cdot g(p_2^{a_2}) \cdot ... \cdot g(p_k^{a_k})

Лема. Нехай — дільник числа . Тоді існує рівно таких чисел , що 1 \le i \le n і НСД(i, n) = d.

► Якщо НСД(i, n) = d, то ділить . Подамо число у вигляді i = d \cdot j. Оскільки ділить , число можна записати у вигляді n = d \cdot (n / d). Тоді:

НСД(i, n) = НСД(d \cdot j, n) = НСД(d \cdot j, d \cdot (n / d)) = d \cdot НСД(j, n / d)

Нас цікавлять такі , для яких НСД(i, n) = d. Тому повинно виконуватися d \cdot НСД(j, n / d) = d. Звідси

НСД(j, n / d) = 1

Кількість чисел , взаємно простих з , дорівнює .

Приклад. Розглянемо число n = 24 і знайдемо всі числа , для яких НСД(i, 24) = 3. За лемою кількість таких чисел дорівнює φ(24 / 3) = φ(8) = 4.

Щоб знайти ці числа, подамо i = 3 \cdot j. Тоді з доведення леми випливає, що повинно виконуватися НСД(j, 8) = 1. Рівність має місце при j \in \{1, 3, 5, 7\}. Отже, НСД(i, 24) = 3 for i \in \{3, 9, 15, 21\}.

Теорема.

g(n) = \sum_{i=1}^{n} \gcd(i,n) = n \sum_{d \mid n} \frac{\varphi(d)}{d}

► Розглянемо всі числа від до і згрупуємо їх залежно від значення НСД(i, n).

Нехай НСД(i, n) = e. Згідно з наведеною вище лемою, кількість таких чисел точно дорівнює . Кожне таке число дає в суму один і той самий внесок, що дорівнює . Тому всі числа , для яких НСД(i, n) = e, разом дають внесок e \cdot φ(n / e).

Значення завжди є дільником числа . Тому, щоб отримати всю суму , потрібно підсумувати ці внески за всіма дільниками числа :

g(n) = \sum_{e \mid n} e \varphi\left(\frac{n}{e}\right)

Зробимо заміну змінної: d = n / e. Тоді e = n / d. Оскільки є дільником , число також є дільником . Підставляючи e = n / d в отриману формулу, отримуємо:

g(n) = \sum_{e \mid n} e \varphi\left(\frac{n}{e}\right) = \sum_{d \mid n} \frac{n}{d}\varphi(d) = n \sum_{d \mid n} \frac{\varphi(d)}{d}

Теорема. Нехай

g(n) = \sum_{i=1}^{n} \gcd(i,n)

Тоді для будь-якого простого і натурального має місце співвідношення:

g(p^a) = (a + 1)p^a - ap^{a–1}

► При a = 1 маємо:

g(p) = НСД(1, p) + НСД(2, p) + ... + НСД(p, p) = (p - 1) + p = 2p - 1

При a = 2, маємо:

= (1 + 1 + … + 1 + p) + \\ (1 + 1 + … + 1 + p) + \\ ... \\ (1 + 1 + … + 1 + p^2) =
= (p - 1 + p) \cdot (p - 1) + (p - 1 + p^2) = \\ (2p - 1) \cdot (p - 1) + (p^2 + p - 1) = \\ 2p^2 - 2p - p + 1 + (p^2 + p - 1) = \\ = 3p^2 - 2p

Обчислимо g(p^a). Значення НСД(i, p^a) може бути тільки дільником числа p^a. Оскільки — просте число, всі дільники p^a мають вигляд p^k, де 0 \le k \le a.

Знайдемо кількість чисел від до p^a, для яких НСД(i, p^a) = p^k. Згідно з наведеною вище лемою, ця кількість дорівнює

φ(p^{a - k}) = p^{a - k} - p^{a - k - 1} (формула~справедлива~для~a \> k)

Крім того, для i = p^a маємо: НСД(i, p^a) = НСД(p^a, p^a) = p^a.

Тому

g(p^a) = \sum_{k=0}^{a-1} p^k \varphi\left(p^{a-k}\right) + p^a = \sum_{k=0}^{a-1} p^k \left(p^{a-k} - p^{a-k-1}\right) + p^a \\ = \sum_{k=0}^{a-1} \left(p^a - p^{a-1}\right) + p^a = a\left(p^a - p^{a-1}\right) + p^a = (a+1)p^a - ap^{a-1}

Приклад. Нехай n = 6.

Тоді

g(6) = \sum_{i=1}^{6} \gcd(i,6) = \\ = НСД(1, 6) + НСД(2, 6) + НСД(3, 6) + НСД(4, 6) + НСД(5, 6) + НСД(6, 6) = \\ = 1 + 2 + 3 + 2 + 1 + 6 = 15

Водночас

g(6) = g(2) \cdot g(3) = \\ (НСД(1, 2) + НСД(2, 2)) \cdot (НСД(1, 3) + НСД(2, 3) + НСД(3, 3)) = \\ (1 + 2) \cdot (1 + 1 + 3) = 3 \cdot 5 = 15

Обчислимо за формулою g(n) = n \sum_{d \mid n} \frac{\varphi(d)}{d}

g(6) = 6 \sum_{d \mid 6} \frac{\varphi(d)}{d} = 6 \cdot \left(\frac{\varphi(1)}{1}+ \frac{\varphi(2)}{2} + \frac{\varphi(3)}{3} + \frac{\varphi(6)}{6} \right) \\ = 6\varphi(1) + 3\varphi(2) + 2\varphi(3) + \varphi(6) = 6 + 3 + 4 + 2 = 15

Обчислимо виходячи з мультиплікативності функції f(x) = НСД(x, n):

g(6) = g(2) \cdot g(3) = (2 \cdot 2 - 1) \cdot (2 \cdot 3 - 1) = 3 \cdot 5 = 15

Приклад. Нехай n = 12.

Тоді

g(12) = \sum_{i=1}^{12} \gcd(i,12) = 1 + 2 + 3 + 4 + 1 + 6 + 1 + 4 + 3 + 2 + 1 + 12 = 40

Водночас

g(12) = g(4) \cdot g(3) = \\ (НСД(1, 4) + НСД(2, 4) + НСД(3, 4) + НСД(4, 4)) \cdot \\ (НСД(1, 3) + НСД(2, 3) + НСД(3, 3)) = \\ (1 + 2 + 1 + 4) \cdot (1 + 1 + 3) = 8 \cdot 5 = 40

Обчислимо за формулою g(n) = n \sum_{d \mid n} \frac{\varphi(d)}{d}:

g(12) = 12 \sum_{d \mid 12} \frac{\varphi(d)}{d} = 12 \cdot \left( \frac{\varphi(1)}{1} + \frac{\varphi(2)}{2} + \frac{\varphi(3)}{3} + \frac{\varphi(4)}{4} + \frac{\varphi(6)}{6} + \frac{\varphi(12)}{12} \right) \\ = 12\varphi(1) + 6\varphi(2) + 4\varphi(3) + 3\varphi(4) + 2\varphi(6) + \varphi(12) \\ = 12 + 6 + 8 + 6 + 4 + 4 = 40

Дільниками числа є: 1, 2, 3, 4, 6, 12. Кількість таких що НСД(i, 12) = d дорівнює . Наприклад НСД(i, 12) = 3 має місце для ϕ(12/3) = ϕ(4) = 2 різних , а саме для i = 3, 9.

Обчислимо виходячи з мультиплікативності функції f(x) = НСД(x, n):

g(12) = g(2^2) \cdot g(3) = (3 \cdot 2^2 - 2 \cdot 2) \cdot (2 \cdot 3 - 1) = 8 \cdot 5 = 40

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

Функція euler обчислює функцію Ейлера.

long long euler(long long n)
{
  long long i, result = n;
  for (i = 2; i * i <= n;i++)
  {
    if (n % i == 0) result -= result / i;
    while (n % i == 0) n /= i;
  }
  if (n > 1) result -= result / n;
  return result;
}

Основна частина програми. Читаємо значення . Обчислимо значення за формулою \sum_{e \mid n} e \varphi\left(\frac{n}{e}\right). Всі дільники числа шукаємо серед чисел від до \lfloor \sqrt{n} \rfloor.

Якщо є дільником , то число також є дільником . Тому при знаходженні кожного дільника i \le \lfloor \sqrt{n} \rfloor, до результату слід додати i \phi(\frac{n}{i}) + \frac{n}{i} \phi(i), що враховує обидва дільники і .

Якщо є повним квадратом і i = sq = \left\lfloor \sqrt{n} \right\rfloor, то дільники і збігаються. У цьому випадку iϕ(\frac{n}{i}) = \frac{n}{i} ϕ(i) і в суму додадуться два однакових доданки. Тому один з них віднімаємо від вже на етапі ініціалізації цієї змінної.

while(scanf("%lld",&n) == 1)
{
  sq = (long long)sqrt(1.0*n);
  res = (sq * sq == n) ? -sq * euler(sq) : 0;

  for (i = 1; i <= sq; i++)
    if(n % i == 0) res = res + i * euler(n/i) + (n / i) * euler(i);
  printf("%lld\n",res);
}

Реалізація алгоритму – з використанням мультиплікативності

Розкладемо число на прості множники:

n = p_1^{a_1} p_2^{a_2} ... p_k^{a_k}

Ми довели, що функція g(n) = \sum_{i=1}^{n} \gcd(i,n) мультиплікативна. Тому

g(n) = g(p_1^{a_1}) \cdot g(p_2^{a_2}) \cdot \ldots \cdot g(p_k^{a_k})

А для степеня простого числа ми довели формулу:

g(p^a) = (a + 1)p^a - ap^{a-1}

Саме ці дві формули безпосередньо використовуються в програмі.

Обробляємо декілька тестів. Читаємо значення .

while(scanf("%lld",&n) == 1)
{

У змінній будемо обчислювати значення .

  res = 1;

Розкладаємо на прості множники число . Перебираємо дільники.

  for (i = 2; i * i <= n; i++)
  {

Якщо число просте, то виокремлюємо множник p = i^a.

    if (n % i == 0)
    {
      a = 0; p = 1;
      while(n % i == 0)
      {
        a++;
        p *= i;
        n /= i;
      }

Множимо результат на

g(p) = g(i^a) = (a + 1) \cdot i^a - a \cdot i^{a - 1} = (a + 1) \cdot p - a \cdot p / i
      res *= (a + 1) * p - a * p / i;
    }
  }

Якщо n > 1, то останній простий множник.

  if (n > 1) res *= (2*n - 1);

Виводимо відповідь.

  printf("%lld\n",res);
}

Java реалізація

import java.util.Scanner;

public class Main
{
  static long euler(long n)
  {
    long result = n;
    for(int i = 2; i <= Math.sqrt(n);i++)
    {
      if (n % i == 0) result -= result / i;
      while (n % i == 0) n /= i;
    }
    if (n > 1) result -= result / n;
    return result;
  }
    
  public static void main(String[] args)
  {
    Scanner con = new Scanner(System.in);
    while(con.hasNext())
    {
      long n = con.nextLong();
      long sq = (long)Math.sqrt(n);
      long res = (sq * sq == n) ? -sq * euler(sq) : 0;
      for(long i = 1; i <= sq; i++)
        if (n % i == 0)
          res = res + i * euler(n/i) + (n / i) * euler(i);
      System.out.println(res);
    }
    con.close();
  }
}