#include
#include
#include
#include
#include
#include
using namespace std;
typedef vector > arr;
const int ile = 6; /* \ */
const int iloczyn = 2* 3* 5* 7* 11* 13 ; /* > zalezne parametry */
const int pt[] = { 2, 3, 5, 7, 11, 13}; /* / nalezy dobrac do rozmiaru */
/* cache'u w procesorze */
void elim (bool v[], const arr::iterator& start, const arr::iterator& end)
{
int j;
for (arr::iterator it = start; it != end; ++it)
{
if (it->second >= iloczyn)
it->second -= iloczyn;
else
{
for (j = it->second; j < iloczyn; j += it->first)
v[j] = false;
it->second = j - iloczyn;
}
}
}
void sito (bool v[], arr& pierwsze, int d)
{
int j, k;
for (int i = 1; i < iloczyn; ++i)
if (v[i])
{
k = d + i;
for (j = i + k; j < iloczyn; j += k)
v[j] = false;
pierwsze.push_back(make_pair(k, j - iloczyn));
}
}
#define przepisz(skad, dokad) memcpy(dokad, skad, iloczyn)
// void przepisz(bool skad[], bool dokad[]) {
// for (int i = 0; i < iloczyn; ++i)
// dokad[i] = skad[i];
// }
int main()
{
int a = 1, b, sqrtb, t, d = 0, n, l, p;
arr pierwsze, przedzialy;
vector wszystkiep;
bool wzorzec[iloczyn], temp[iloczyn];
for (int i = 0; i < iloczyn; ++i)
wzorzec[i] = true;
cin >> b >> n;
wszystkiep.reserve(1.25506 * b / log(b)); // gorne ograniczenie funkcji pi(n)
for (int i = 0; i < n; ++i)
{
cin >> l;
cin >> p;
przedzialy.push_back(make_pair(l, p));
}
for (int i = 0; i < ile; ++i)
pierwsze.push_back(make_pair(pt[i], 0));
elim(wzorzec, pierwsze.begin(), pierwsze.end());
przepisz(wzorzec, temp);
temp[1] = false;
sito(temp, pierwsze, 0);
sqrtb = (int) sqrt((double) b);
t = sqrtb / iloczyn;
sqrtb = (t + 1) * iloczyn; // zaokraglenie pierwastka do konca przedzialu
for (int i = 0; i < t; ++i)
{
d += iloczyn;
przepisz(wzorzec, temp);
elim(temp, pierwsze.begin() + ile, pierwsze.end());
sito(temp, pierwsze, d);
}
if (a < sqrtb)
{
for (arr::const_iterator it = pierwsze.begin(); it != pierwsze.end(); ++it)
if (it->first <= b && it->first >= a)
wszystkiep.push_back(it->first); // it->first jest pierwsze
}
int ml, ms;
d = sqrtb;
while (b > d)
{
ms = ml = 0;
przepisz(wzorzec, temp);
elim(temp, pierwsze.begin() + ile, pierwsze.end());
if (a > d || b < d + iloczyn)
{
for (int i = 0; i < iloczyn; ++i)
if (temp[i])
wszystkiep.push_back(d + i); //d + i jest pierwsze
}
else
{
for (int i = 0; i < iloczyn; ++i)
if (temp[i])
wszystkiep.push_back(d + i); //d + i jest pierwsze
}
d += iloczyn;
}
for(int i = 0; i < n; ++i)
cout << distance(lower_bound(wszystkiep.begin(), wszystkiep.end(), przedzialy[i].first),
upper_bound(wszystkiep.begin(), wszystkiep.end(), przedzialy[i].second)
)
<< endl;
return 0;
}
Jeśli Cię to jeszcze interesuje, to jest tu działający program z zoptymalizowanym sitem (miałem podobny i przerobiłem). Problemem jest tutaj przechowywanie wszystkich liczb pierwszych w wektorze wszystkiep (szybko braknie pamięci). Można w locie dodawać do przedziałów bez spamiętywania wszystkich liczb pierwszych, ale do tego trzeba jakiejś szybkiej struktury (może jakieś drzewa przedziałowe?).
EDIT:
Poprawka, wziąłem zły logarytm