1+ #include < bits/stdc++.h>
2+
3+ using namespace std ;
4+
5+ using ll = long long ;
6+
7+ vector<int > sieve (int n) {
8+ vector<bool > b (n+1 );
9+ for (int i = 3 ; i*i <= n; i += 2 ) {
10+ if (b[i] == 0 ) {
11+ for (int j = i*i; j <= n; j += 2 *i) {
12+ b[j] = 1 ;
13+ }
14+ }
15+ }
16+
17+ vector<int > primes = {2 };
18+ for (int i = 3 ; i <= n; i += 2 ) {
19+ if (b[i] == 0 ) primes.push_back (i);
20+ }
21+ return primes;
22+ }
23+
24+ // at least sqrt(n) for pi(n)
25+ int const sqrt_limit = 1e7 + 1 ;
26+
27+ auto primes = sieve(sqrt_limit);
28+
29+ using ii = pair<ll, int >;
30+
31+ map<ii, ll> phi_cache;
32+
33+ ll phi (ll x, int a) {
34+ if (phi_cache.count ({x, a})) return phi_cache[{x, a}];
35+
36+ if (a == 1 ) {
37+ return (x+1 )/2 ;
38+ }
39+
40+ ll res = phi (x, a-1 ) - phi (x / primes[a-1 ], a-1 );
41+ phi_cache[{x, a}] = res;
42+
43+ return res;
44+ }
45+
46+ map<ll, ll> pi_cache;
47+
48+ ll pi (ll x) {
49+ if (pi_cache.count (x)) return pi_cache[x];
50+
51+ if (x < sqrt_limit) {
52+ return upper_bound (primes.begin (), primes.end (), x) - primes.begin ();
53+ }
54+
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 ));
58+
59+ ll res = phi (x, a) + (b+a-2 )*(b-a+1 )/2 ;
60+
61+ for (ll i = a+1 ; i <= b; i++) {
62+ ll w = x / primes[i-1 ];
63+ ll b_i = pi (pow (w, 1.0 /2 ));
64+ res -= pi (w);
65+
66+ if (i <= c) {
67+ for (ll j = i; j <= b_i; j++) {
68+ res -= pi (w / primes[j-1 ]) - j + 1 ;
69+ }
70+ }
71+ }
72+
73+ pi_cache[x] = res;
74+ return res;
75+ }
76+
77+ int main () {
78+ ll n;
79+ cin >> n;
80+
81+ cout << pi (n) << " \n " ;
82+ }
0 commit comments