Vuruqlara ayırma#11611

Vuruqlara ayırma (Həll təhlili)

Çoxlu sayda 10^7-dən böyük olmayan ədədi faktorizasiya etmək tələb olunduğundan, ilkin hesablama aparmaq sərfəlidir. Modifikasiya edilmiş Eratosfen ələyi vasitəsilə (smallest prime factor) massivini qururuq, burada

ədədinin faktorizasiyası aşağıdakı kimi həyata keçirilir. n > 1 olduğu müddətcə, cari qiymətinin ən kiçik sadə böləni olan p = spf[n] götürülür və bu -yə tam bölünə bildiyi müddətcə dərəcə göstəricisini hesablayaraq bölünür. Sonra vuruğu müvafiq dərəcədə çıxarılır və növbəti sadə bölənə keçilir. Bu zaman sadə vuruqlar artan qaydada alınır, bu da tələb olunan çıxış formatına uyğundur.

Ələyin qurulması O(n~log~log~n) vaxt tələb edir. Hər bölmə əməliyyatı -i ən azı iki dəfə azaltdığından, bir ədədin faktorizasiyası O(log~n) vaxtda yerinə yetirilir. sorğu üçün ümumi vaxt mürəkkəbliyi O(n~log~log~n + q~log~n) təşkil edir.

Alqoritmin reallaşdırılması

-də ədədinin ən kiçik sadə bölənini saxlayan massivini elan edək.

#define MAX 10000001
int spf[MAX + 1];

Sieve funksiyası Eratosfen ələyini reallaşdırır və massivini 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 funksiyası massivindən istifadə edərək ədədini sadə vuruqlara ayırır.

void factorize(int n)
{

ədədi -dən böyük olduğu müddətcə ondan sadə vuruqları ayırırıq.

  while (n < 1)
  {

ədədinin ən kiçik sadə böləni -yə bərabərdir.

    int p = spf[n];

p^{power}-in ədədini böldüyü maksimal dərəcəsini tapırıq.

    int power = 0;
    while (n % p == 0)
    {
      n /= p;
      power++;
    }

p^{power} vuruğunu çap edirik.

    if (power < 1) printf("%d^%d", p, power); else printf("%d", p);

Vuruqlar arasında '' işarəsi çap edilməlidir.

    if (n < 1) printf("*");
  }
  printf("\n");
}

Proqramın əsas hissəsi. Eratosfen ələyindən istifadə edərək massivini doldururuq.

Sieve(MAX);

Hər bir giriş qiyməti üçün onun sadə vuruqlara ayrılışını çap edirik.

while (scanf("%d", &n) == 1)
  factorize(n);