Teorema. Se la funzione è moltiplicativa, allora la funzione sommatoria
è 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
Corollario. Consideriamo la funzione f(n) = MCD(n, c), dove — è una costante. Mostriamo che questa funzione è moltiplicativa.
Se e sono coprimi, allora
Di conseguenza la funzione f(n) = MCD(n, c) è moltiplicativa.
Esempio. Calcoliamo MCD(36, 90) utilizzando la proprietà di moltiplicatività.
Ora consideriamo la sua funzione sommatoria:
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
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:
Ci interessano quegli per cui MCD(i, n) = d. Pertanto deve valere d \cdot MCD(j, n / d) = d. Da ciò segue
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.
► 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 :
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:
Teorema. Sia
Allora per ogni numero primo e naturale vale la relazione:
► Per a = 1 abbiamo:
Per a = 2, abbiamo:
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
Inoltre, per i = p^a abbiamo: MCD(i, p^a) = MCD(p^a, p^a) = p^a.
Pertanto
Esempio. Sia n = 6.
Allora
Allo stesso tempo
Calcoliamo con la formula g(n) = n \sum_{d \mid n} \frac{\varphi(d)}{d}
Calcoliamo a partire dalla moltiplicatività della funzione f(x) = MCD(x, n):
Esempio. Sia n = 12.
Allora
Allo stesso tempo
Calcoliamo con la formula g(n) = n \sum_{d \mid n} \frac{\varphi(d)}{d}:
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):
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:
Abbiamo dimostrato che la funzione g(n) = \sum_{i=1}^{n} \gcd(i,n) è moltiplicativa. Di conseguenza
E per la potenza di un numero primo abbiamo dimostrato la formula:
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
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();
}
}