Mam takie zadanie
Przypomnijmy, że liczba doskonała to liczba naturalna większa od 1, która, jest sumą wszystkich swoich dzielników właściwych. Liczbą doskonałą drugiego rodzaju nazywamy liczbę naturalną większą od 1, która jest iloczynem wszystkich swoich dzielników właściwych. Przykładowo dzielnikami właściwymi liczby 27 są 1, 3 i 9, a więc 27 jest liczbą doskonałą drugiego rodzaju: 1 · 3 · 9 = 27. Dzielnik właściwy to dzielnik naturalny liczby, różny od niej samej. Chcielibyśmy się dowiedzieć, ile jest liczb doskonałych drugiego rodzaju zawartych w pewnych przedziałach.
Wejście
W pierwszym wierszu wejścia znajduje się jedna liczba całkowita d (1<= d <= 30)
oznaczająca liczbę przypadków testowych. Kolejnych d wierszy zawiera po
dwie liczby całkowite a i b (2 <= a < b ¬<=1 000 000).
Wyjście
Dla każdego przypadku testowego należy wypisać jedną liczbę całkowitą
równą liczbie liczb doskonałych drugiego rodzaju zawartych w przedziale
[a..b].
I taka odpowiedź
Zadanie można rozwiązać w czasie O(d + k log log k), gdzie k to największa
wartość ze wszystkich końców przedziałów.
• Wiele liczb półpierwszych jest również liczbami doskonałymi drugiego
rodzaju. Liczby doskonałe drugiego rodzaju nie zawsze są liczbami półpierwszymi. Przykładowo, liczba 27 = 3 · 3 · 3 nie jest półpierwsza.
• Jedynymi liczbami półpierwszymi, które nie są doskonałe, są liczby postaci p^2, gdzie p jest liczbą pierwszą.
• Jedynymi liczbami doskonałymi drugiego rodzaju, które nie są półpierwsze,są liczby postaci p^3, gdzie p jest liczbą pierwszą. Dzielnikami właściwymi
takiej liczby są p i p^2
• Dla każdej liczby zapisujemy, czy jest liczbą doskonałą drugiego rodzaju, po czym tworzymy sumy prefiksowe — liczbę liczb doskonałych w każdym
prefiksie.
for (int i = 2; i * i * i <= k; i++)
if (F[i] == 0)
pref[i * i * i] = 1;
for (int i = 2; i <= k; i++) {
if (F[i] != 0 && F[i / F[i]] == 0 && F[i]*F[i] != i)
pref[i] = 1;
pref[i] += pref[i - 1];
}
Mój algorytm
#include "bits/stdc++.h"
using namespace std;
int main()
{
ios_base::sync_with_stdio(0);
int d, k;
cin >> d;
int * przedzialy = new int[d*2];
for (int i = 0; i < d * 2; i += 2){
cin >> przedzialy[i] >> przedzialy[i+1];
k = max(k, przedzialy[i+1]);
}
vector <int> F(k+1, 0);
for (int i = 2; i * i <= k; i++){
if (F[i] == 0){
for (int j = i*i; j <= k; j += i)
if (F[j] == 0)
F[j] = i;
}
}
vector <int> pref(k+1, 0);
for (int i = 2; i * i * i < k; i++){
if (F[i] == 0)
pref[i * i * i] = 1;
}
for (int i = 2; i <= k; i++) {
if (F[i] != 0 && F[i / F[i]] == 0 && F[i]*F[i] != i)
pref[i] = 1;
pref[i] += pref[i - 1];
}
//tablica pref jest dziwna bo dopiero komorka 6 zamiast 5 reprezentuje liczbe 4
//gdzie popelniam blad?
for (int i = 0; i < d * 2; i += 2){
cout << pref[przedzialy[i+1]+1] - pref[przedzialy[i]] << endl;
}
return 0;
}
Tablica pref w zły sposób reprezentuje liczby, pomoże mi ktoś zrozumieć gdzie robię błąd?