10^7'yi aşmayan çok sayıda sayıyı çarpanlarına ayırmak gerektiğinden, bir ön hesaplama yapmak avantajlıdır. Değiştirilmiş Eratosthenes eleği yardımıyla, (smallest prime factor - en küçük asal çarpan) dizisini oluşturacağız; burada
, sayısının en küçük asal çarpanını içerir
sayısının çarpanlarına ayrılması şu şekilde gerçekleştirilir. n > 1 olduğu sürece, 'nin şu anki değerinin en küçük asal çarpanı olan p = spf[n]'yi alıyoruz ve bölme tam olarak gerçekleştiği sürece 'yi 'ye bölüp üssü sayıyoruz. Ardından çarpanını ilgili üssüyle birlikte yazdırıyoruz ve bir sonraki asal çarpana geçiyoruz. Bu durumda asal çarpanlar artan sırada elde edilir, bu da gerekli çıktı biçimine karşılık gelir.
Eleğin oluşturulması O(n~log~log~n) zaman gerektirir. Her bölme işlemi 'yi en az yarıya indirdiğinden, bir sayının çarpanlarına ayrılması O(log~n) sürede gerçekleştirilir. sorgu için toplam zaman karmaşıklığı O(n~log~log~n + q~log~n) olur.
Algoritmanın Gerçekleştirilmesi
'nin sayısının en küçük asal çarpanını içerdiği dizisini tanımlayalım.
#define MAX 10000001
int spf[MAX + 1];Sieve fonksiyonu Eratosthenes eleğini gerçekleştirir ve dizisini doldurur.
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;
}factorize fonksiyonu, dizisini kullanarak sayısını asal çarpanlarına ayırır.
void factorize(int n)
{sayısı 'den büyük olduğu sürece asal çarpanları ayıklıyoruz.
while (n > 1)
{sayısının en küçük asal çarpanı 'ye eşittir.
int p = spf[n];p^{power}'nin sayısını böldüğü maksimum üssünü buluyoruz.
int power = 0;
while (n % p == 0)
{
n /= p;
power++;
}p^{power} çarpanını yazdırıyoruz.
if (power > 1) printf("%d^%d", p, power); else printf("%d", p);Çarpanlar arasında '' işareti yazdırılmalıdır.
if (n > 1) printf("*");
}
printf("\n");
}Programın ana bölümü. Eratosthenes eleğini kullanarak dizisini dolduruyoruz.
Sieve(MAX);Her giriş değeri için, onun asal çarpanlara ayrılmış halini yazdırıyoruz.
while (scanf("%d", &n) == 1)
factorize(n);