Informatyczny kącik olimpijski
Liczby
W tym miesiącu omówimy zadanie Liczby, które pojawiło się podczas rundy 72. na portalu codeforces.com.
W zadaniu należy, mając dane liczby naturalne wyznaczyć liczbę liczb naturalnych w przedziale których najmniejszym dzielnikiem, większym od jest Zauważmy najpierw, że wystarczy umieć obliczać wyniki dla przedziałów postaci ponieważ wynik dla przedziału jest różnicą wyników dla przedziałów i Ponadto, jeśli nie jest liczbą pierwszą, to wynik jest równy 0, ponieważ jeśli liczba jest podzielna przez to jest też podzielna przez każdy dzielnik a skoro nie jest pierwsza, to ma dzielnik większy od i mniejszy od Załóżmy teraz, że jest pierwsza. Zadanie można rozwiązać w czasie wyznaczając dla każdej liczby z przedziału jej najmniejszy dzielnik, większy od 1, za pomocą sita Eratostenesa. Rozwiązanie to dla jest dalece niewystarczające. Zauważmy, że można je łatwo usprawnić. Każda liczba, której najmniejszy dzielnik jest równy jest postaci gdzie nie ma dzielników większych od i mniejszych od Wystarczy zatem zliczyć takie -y z przedziału które nie mają dzielników pierwszych mniejszych od Można to zrobić, iterując kolejne liczby pierwsze mniejsze od i zaznaczając w tablicy liczby podzielne przez którąś z nich.
Rozwiązanie to wykona dla każdej liczby pierwszej mniejszej od operacji, czyli łącznie
Dla rozwiązanie takie jest wystarczające. Jeśli natomiast jest mniejsze od to liczb pierwszych mniejszych od jest nie więcej niż Niech teraz oznacza zbiór liczb podzielnych przez oraz leżących w przedziale Naszym zadaniem jest obliczenie
Możemy to zrobić, korzystając z zasady włączeń i wyłączeń. W tym celu musimy umieć obliczyć Jest to zbiór liczb podzielnych przez leżących w przedziale czyli ma elementów.
Całe rozwiązanie działa w czasie
Na to zadanie można też spojrzeć inaczej. Niech będzie liczbą liczb w przedziale które nie mają dzielników większych od i mniejszych od Wykażemy, że
Istotnie, liczb nie większych od których najmniejszym dzielnikiem jest jest ponieważ każda taka liczba jest postaci gdzie nie ma dzielników większych od i mniejszych od a czyli Wszystkich liczb w przedziale jest a każda z nich albo ma dzielnik pierwszy mniejszy od wówczas zostanie odjęta dokładnie raz, dla będącego jej najmniejszym dzielnikiem pierwszym, albo nie ma i wtedy nie zostanie odjęta. Liczba liczb w przedziale których najmniejszym dzielnikiem jest jest równa Zadanie można rozwiązać, obliczając wartość funkcji rekurencyjnie korzystając z tego wzoru. Niech będą kolejnymi liczbami pierwszymi, a liczbą operacji wykonanych przez algorytm dla liczby pierwszej Wówczas Rozwiązaniem tego równania jest czyli całe rozwiązanie będzie działało w czasie co jest zdecydowanie za wolne.
Rozwiązanie to można łatwo przyspieszyć. Wystarczy zauważyć, że jeśli to jedyną liczbą w przedziale niemającą dzielników większych od i mniejszych od jest więc i w każdym wywołaniu rekurencyjnym obliczającym wynik dla zwracać bez dalszych wywołań rekurencyjnych. Wykażemy, że rozwiązanie z tą optymalizacją obliczające wykona co najwyżej wywołań rekurencyjnych. Rozważmy gałąź w drzewie rekursji, w której algorytm wykonał kolejno dzielenia przez Oznacza to, że w przedostatnim wywołaniu obliczał Skoro nie zwrócił wyniku od razu, tylko wykonał następne wykonanie rekurencyjne, to skąd wynika, że czyli Algorytm w danym wywołaniu przegląda jedynie liczby pierwsze, mniejsze od poprzedniej, zatem skąd otrzymujemy Liczby są pierwsze, więc dla różnych wywołań rekurencyjnych iloczyny będą parami różne, więc liczba tych wywołań nie przekroczy
Prezentowane rozwiązanie potrzebuje listy liczb pierwszych mniejszych od Można ją, oczywiście, wyznaczyć, używając sita Eratostenesa, w czasie Ostatecznie, całe rozwiązanie obliczające działa w czasie