Skip to content

Commit cea895c

Browse files
committed
Fixed precision issues for very large values of n
1 parent 3b262d3 commit cea895c

File tree

1 file changed

+26
-6
lines changed

1 file changed

+26
-6
lines changed

math/prime_count.cpp

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,26 @@ using namespace std;
44

55
using ll = long long;
66

7+
ll isqrt(ll x) {
8+
ll l = 0, r = 1e9;
9+
while (r-l > 1) {
10+
ll m = (l+r)/2;
11+
if (m*m <= x) l = m;
12+
else r = m;
13+
}
14+
return l;
15+
}
16+
17+
ll icbrt(ll x) {
18+
ll l = 0, r = 1e6;
19+
while (r-l > 1) {
20+
ll m = (l+r)/2;
21+
if (m*m*m <= x) l = m;
22+
else r = m;
23+
}
24+
return l;
25+
}
26+
727
vector<int> sieve(int n) {
828
vector<bool> b(n+1);
929
for (int i = 3; i*i <= n; i += 2) {
@@ -22,7 +42,8 @@ vector<int> sieve(int n) {
2242
}
2343

2444
// at least sqrt(n) for pi(n)
25-
int const sqrt_limit = 1e7 + 1;
45+
// bigger values may be faster
46+
int const sqrt_limit = isqrt(1e12) + 1;
2647

2748
auto primes = sieve(sqrt_limit);
2849

@@ -52,15 +73,15 @@ ll pi(ll x) {
5273
return upper_bound(primes.begin(), primes.end(), x) - primes.begin();
5374
}
5475

55-
ll a = pi(pow(x, 1.0/4));
56-
ll b = pi(pow(x, 1.0/2));
57-
ll c = pi(pow(x, 1.0/3));
76+
ll a = pi(isqrt(isqrt(x)));
77+
ll b = pi(isqrt(x));
78+
ll c = pi(icbrt(x));
5879

5980
ll res = phi(x, a) + (b+a-2)*(b-a+1)/2;
6081

6182
for (ll i = a+1; i <= b; i++) {
6283
ll w = x / primes[i-1];
63-
ll b_i = pi(pow(w, 1.0/2));
84+
ll b_i = pi(sqrt(w));
6485
res -= pi(w);
6586

6687
if (i <= c) {
@@ -73,7 +94,6 @@ ll pi(ll x) {
7394
pi_cache[x] = res;
7495
return res;
7596
}
76-
7797
int main() {
7898
ll n;
7999
cin >> n;

0 commit comments

Comments
 (0)