Il problema di Longge#1128

Il problema di Longge (Editoriale)

Teorema. Se la funzione è moltiplicativa, allora la funzione sommatoria

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

è anch'essa moltiplicativa.

► Siano x, y \in N, con e coprimi.

Siano x_1, x_2, ..., x_k — tutti i divisori di , e y_1, y_2, ..., y_m — tutti i divisori di .

Poiché e sono coprimi, ogni divisore x_i è coprimo con ogni divisore y_j. Quindi MCD(x_i, y_j) = 1. Ciò significa che il prodotto x_i \cdot y_j è un divisore del numero x \cdot y.

Inoltre, ogni prodotto x_i \cdot y_j fornisce un divisore distinto del numero x \cdot y, e in questo modo otteniamo tutti i divisori del numero x \cdot y. Di conseguenza, la somma su tutti i divisori del numero x \cdot y può essere rappresentata come una doppia somma su tutte le coppie di divisori x_i e y_j. Allora

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)

Corollario. Consideriamo la funzione f(n) = MCD(n, c), dove — è una costante. Mostriamo che questa funzione è moltiplicativa.

Se e sono coprimi, allora

f(x \cdot y) = MCD(x \cdot y, c) = MCD(x, c) \cdot MCD(y, c) = f(x) \cdot f(y)

Di conseguenza la funzione f(n) = MCD(n, c) è moltiplicativa.

Esempio. Calcoliamo MCD(36, 90) utilizzando la proprietà di moltiplicatività.

MCD(36, 90) = MCD(4 \cdot 9, 90) = MCD(4, 90) \cdot MCD(9, 90) = 2 \cdot 9 = 18

Ora consideriamo la sua funzione sommatoria:

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

Dal teorema precedente sappiamo che la funzione sommatoria di una funzione moltiplicativa è anch'essa moltiplicativa. Di conseguenza, anche la funzione è moltiplicativa.

Se scomponiamo in potenze di numeri primi n = p_1^{a_1} p_2^{a_2}...p_k^{a_k}, allora

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})

Lemma. Sia — un divisore del numero . Allora esistono esattamente numeri tali che 1 \le i \le n e MCD(i, n) = d.

► Se MCD(i, n) = d, allora divide . Rappresentiamo il numero nella forma i = d \cdot j. Poiché divide , il numero può essere scritto nella forma n = d \cdot (n / d). Allora:

MCD(i, n) = MCD(d \cdot j, n) = MCD(d \cdot j, d \cdot (n / d)) = d \cdot MCD(j, n / d)

Ci interessano quegli per cui MCD(i, n) = d. Pertanto deve valere d \cdot MCD(j, n / d) = d. Da ciò segue

MCD(j, n / d) = 1

Il numero di valori coprimi con è pari a .

Esempio. Consideriamo il numero n = 24 e troviamo tutti i numeri per cui MCD(i, 24) = 3. Secondo il lemma, il numero di tali valori è pari a φ(24 / 3) = φ(8) = 4.

Per trovare questi numeri, rappresentiamo i = 3 \cdot j. Allora dalla dimostrazione del lemma segue che deve valere MCD(j, 8) = 1. L'uguaglianza vale per j \in \{1, 3, 5, 7\}. Di conseguenza, MCD(i, 24) = 3 for i \in \{3, 9, 15, 21\}.

Teorema.

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

► Consideriamo tutti i numeri da a e raggruppiamoli in base al valore di MCD(i, n).

Sia MCD(i, n) = e. Secondo il lemma sopra riportato, il numero di tali valori è esattamente . Ogni valore di questo tipo contribuisce alla somma con lo stesso valore, pari a . Pertanto tutti i numeri per cui MCD(i, n) = e forniscono insieme un contributo pari a e \cdot φ(n / e).

Il valore è sempre un divisore del numero . Perciò, per ottenere l'intera somma , è necessario sommare questi contributi su tutti i divisori del numero :

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

Effettuiamo un cambio di variabile: d = n / e. Allora e = n / d. Poiché è un divisore di , anche il numero è un divisore di . Sostituendo e = n / d nella formula ottenuta, otteniamo:

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}

Teorema. Sia

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

Allora per ogni numero primo e naturale vale la relazione:

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

► Per a = 1 abbiamo:

g(p) = MCD(1, p) + MCD(2, p) + ... + MCD(p, p) = (p - 1) + p = 2p - 1

Per a = 2, abbiamo:

= (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

Calcoliamo g(p^a). Il valore MCD(i, p^a) può essere soltanto un divisore del numero p^a. Poiché — è un numero primo, tutti i divisori di p^a hanno la forma p^k, dove 0 \le k \le a.

Troviamo il numero di valori da a p^a per cui MCD(i, p^a) = p^k. Secondo il lemma sopra riportato, questo numero è pari a

φ(p^{a - k}) = p^{a - k} - p^{a - k - 1} (formula~valida~per~a \gt k)

Inoltre, per i = p^a abbiamo: MCD(i, p^a) = MCD(p^a, p^a) = p^a.

Pertanto

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}

Esempio. Sia n = 6.

Allora

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

Allo stesso tempo

g(6) = g(2) \cdot g(3) = \\ (MCD(1, 2) + MCD(2, 2)) \cdot (MCD(1, 3) + MCD(2, 3) + MCD(3, 3)) = \\ (1 + 2) \cdot (1 + 1 + 3) = 3 \cdot 5 = 15

Calcoliamo con la formula 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

Calcoliamo a partire dalla moltiplicatività della funzione f(x) = MCD(x, n):

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

Esempio. Sia n = 12.

Allora

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

Allo stesso tempo

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

Calcoliamo con la formula 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

I divisori del numero sono: 1, 2, 3, 4, 6, 12. Il numero di valori tali che MCD(i, 12) = d è pari a . Ad esempio MCD(i, 12) = 3 si verifica per ϕ(12/3) = ϕ(4) = 2 valori distinti di , ossia per i = 3, 9.

Calcoliamo a partire dalla moltiplicatività della funzione f(x) = MCD(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

Implementazione dell'algoritmo

La funzione euler calcola la funzione di Eulero.

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;
}

Parte principale del programma. Leggiamo il valore di . Calcoliamo il valore di con la formula \sum_{e \mid n} e \varphi\left(\frac{n}{e}\right). Cerchiamo tutti i divisori del numero tra i numeri da a \lfloor \sqrt{n} \rfloor.

Se è un divisore di , allora anche il numero è un divisore di . Pertanto, nel trovare ogni divisore i \le \lfloor \sqrt{n} \rfloor, al risultato bisogna aggiungere i \phi(\frac{n}{i}) + \frac{n}{i} \phi(i), che tiene conto di entrambi i divisori e .

Se è un quadrato perfetto e i = sq = \left\lfloor \sqrt{n} \right\rfloor, allora i divisori e coincidono. In questo caso iϕ(\frac{n}{i}) = \frac{n}{i} ϕ(i) e nella somma verrebbero aggiunti due addendi identici. Per questo motivo, uno di essi viene sottratto da già in fase di inizializzazione di questa variabile.

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);
}

Implementazione dell'algoritmo – utilizzando la moltiplicatività

Scomponiamo il numero in fattori primi:

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

Abbiamo dimostrato che la funzione g(n) = \sum_{i=1}^{n} \gcd(i,n) è moltiplicativa. Di conseguenza

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

E per la potenza di un numero primo abbiamo dimostrato la formula:

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

Sono proprio queste due formule ad essere utilizzate direttamente nel programma.

Elaboriamo più casi di test. Leggiamo il valore di .

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

Nella variabile calcoleremo il valore di .

  res = 1;

Scomponiamo in fattori primi il numero . Esaminiamo i divisori.

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

Se il numero è primo, isoliamo il fattore p = i^a.

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

Moltiplichiamo il risultato per

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;
    }
  }

Se n > 1, allora è l'ultimo fattore primo.

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

Stampiamo la risposta.

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

Implementazione in 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();
  }
}