Informatyczny kącik olimpijski
Liczby prawie pół-pierwsze
Tym razem omówimy zadanie Liczby prawie pół-pierwsze, które pojawiło się na Sobotnim Kole Naukowym (25.11.2017) organizowanym przez Stowarzyszenie Talent w III Liceum Ogólnokształcącym w Gdyni.
Definicja. Liczbę nazywamy prawie pół-pierwszą, jeśli jest iloczynem dwóch liczb pierwszych
gdzie
Liczby
i
są prawie pół-pierwsze. Natomiast liczby
i
nie są prawie pół-pierwsze.
Zadanie. Dane są dwie liczby całkowite i
Oblicz, ile jest liczb prawie pół-pierwszych na przedziale
Rozwiązanie
Pierwszy pomysł, który nasuwa się po przeczytaniu treści, polega na przejrzeniu wszystkich liczb całkowitych z przedziału i zliczeniu tych, które są prawie pół-pierwsze. Liczba prawie pół-pierwsza zawiera dokładnie dwie liczby pierwsze nie większe niż
w rozkładzie na czynniki pierwsze. Rozkład na czynniki pierwsze liczby całkowitej
możemy znaleźć w czasie
(przeglądamy potencjalne dzielniki pierwsze z przedziału
). Rozwiązanie działa w czasie
Rozwiązanie
W tym podejściu, podobnie jak wcześniej, dla każdej liczby całkowitej z przedziału sprawdzimy, czy jest ona prawie pół-pierwsza.
Zacznijmy od stworzenia takiej tablicy że
dla każdego
oznacza najmniejszy dzielnik pierwszy
W tym celu wystarczy nieznacznie zmodyfikować sito Eratostenesa. Zamiast zapamiętywać informację, czy liczba jest pierwsza czy złożona, będziemy pamiętali jej najmniejszy dzielnik, będący liczbą pierwszą. Strukturę budujemy w czasie
Wówczas w czasie stałym możemy stwierdzić, że:
jest pierwsze, jeśli:
jest prawie pół-pierwsze, jeśli:
Wtedy jej dzielnikami pierwszymi sąi
Po wygenerowaniu zliczamy liczby prawie pół-pierwsze z przedziału
Rozwiązanie działa w czasie
Rozwiązanie
Niech oraz
dla każdego
wskazuje, czy
jest pierwsze
czy złożone
Dla pozostałych
niech
obliczamy za pomocą sita Eratostenesa. Dodatkowo stwórzmy taką tablicę
że
dla każdego
będzie oznaczało najmniejszy dzielnik pierwszy
Konstrukcja
jest następująca. Najpierw przypisujemy
dla każdego
Następnie dla każdej liczby pierwszej
przeglądamy jej wielokrotności w przedziale
czyli liczby
i aktualizujemy ich najmniejszy dzielnik pierwszy. Zauważmy, że wielokrotności
w przedziale
jest co najwyżej
wielokrotności
jest co najwyżej
itd. Zatem konstrukcja struktury zajmuje
operacji.
Na koniec zliczamy liczby prawie pół-pierwsze z przedziału czyli takie
że:
![p ′ ′ ∧T[′]=1 S[p] /= p∧ S [p] ⩽M . S[p]](/math/temat/informatyka/algorytmy/2019/02/28/Liczby_prawie_pol-pierwsze/3x-7fab6cd205c1098a7e4dd0501dc289342802ec3e-dm-33,33,33-FF,FF,FF.gif)
Rozwiązanie
Niech będzie taką funkcją, że
oznacza liczbę liczb prawie pół-pierwszych na przedziale
Wówczas liczb prawie pół-pierwszych na przedziale
jest
Opiszemy teraz, jak policzyć dla
Zacznijmy od wygenerowania ciągu kolejnych liczb pierwszych nie większych niż
Oznaczmy ten ciąg jako
Początkowymi wyrazami ciągu są:
itd. Liczby pierwsze możemy znaleźć za pomocą sita Eratostenesa. Zauważmy, że tylko elementy ciągu
mogą występować w rozkładzie na czynniki pierwsze liczb prawie pół-pierwszych. Zatem:

Wartość możemy policzyć naiwnie, przeglądając wszystkie pary elementów ciągu
Niestety takie rozwiązanie jest wolne, ponieważ przegląda się
par elementów, gdzie
(tyle jest liczb pierwszych nie większych niż
).
Na szczęście możemy to przyspieszyć. Niektóre pary będziemy zliczali "hurtowo". Dokładniej, dla każdego wyznaczymy takie największe
że
Jeśli takie
nie istnieje, to niech
Wówczas liczby postaci
są prawie pół-pierwsze. Zaś wszystkich par jest
Algorytm przebiega następująco. Najpierw naiwnie znajdujemy
przeglądając przedział indeksów
Następnie kolejno wyznaczamy wartości
Obserwacja: Dla każdego zachodzi
Dowód: Wiemy, że oraz
Stąd
Zatem
Na mocy powyższej obserwacji, szukanie wartości możemy rozpocząć od
i zmniejszać ją dopóki
W ten sposób wykonamy
operacji podczas obliczania
Całe rozwiązanie działa w czasie