Poiché è richiesto fattorizzare molti numeri non superiori a 10^7, conviene eseguire un precalcolo. Utilizzando una versione modificata del crivello di Eratostene, costruiamo l'array (smallest prime factor), dove
contiene il più piccolo divisore primo del numero
La fattorizzazione del numero viene eseguita nel modo seguente. Finché n > 1, prendiamo p = spf[n], il più piccolo divisore primo del valore corrente di , e dividiamo per finché la divisione risulta esatta, contando l'esponente. Successivamente stampiamo il fattore elevato alla potenza corrispondente e passiamo al divisore primo successivo. I fattori primi vengono così ottenuti in ordine crescente, il che corrisponde al formato di output richiesto.
La costruzione del crivello richiede un tempo O(n~log~log~n). Ogni divisione riduce di almeno la metà, quindi la fattorizzazione di un singolo numero viene eseguita in O(log~n). La complessità temporale totale per richieste è pari a O(n~log~log~n + q~log~n).
Implementazione dell'algoritmo
Dichiariamo l'array , in cui contiene il più piccolo divisore primo del numero .
#define MAX 10000001
int spf[MAX + 1];La funzione Sieve implementa il crivello di Eratostene e riempie l'array .
void Sieve(int n)
{
for (int i = 0; i < n; i++)
spf[i] = i;
for (int i = 2; i <= sqrt(n); i++)
if (spf[i] == i)
for (int j = i * i; j < n; j += i)
if (spf[j] == j) spf[j] = i;
}La funzione factorize scompone il numero nei suoi fattori primi, utilizzando l'array .
void factorize(int n)
{Estraiamo i fattori primi dal numero finché esso è maggiore di .
while (n > 1)
{Il più piccolo divisore primo del numero è uguale a .
int p = spf[n];Troviamo la potenza massima per cui p^{power} divide il numero .
int power = 0;
while (n % p == 0)
{
n /= p;
power++;
}Stampiamo il fattore p^{power}.
if (power > 1) printf("%d^%d", p, power); else printf("%d", p);Tra i fattori va stampato il simbolo ''.
if (n > 1) printf("*");
}
printf("\n");
}Parte principale del programma. Riempiamo l'array utilizzando il crivello di Eratostene.
Sieve(MAX);Per ogni valore di input stampiamo la sua scomposizione in fattori primi.
while (scanf("%d", &n) == 1)
factorize(n);