@@ -43,28 +43,33 @@ vector<int> sieve(int n) {
43
43
44
44
// at least sqrt(n) for pi(n)
45
45
// bigger values may be faster
46
- int const sqrt_limit = isqrt(1e12 ) + 1 ;
46
+ // for values up to 1e12 the fastest is around 1e8
47
+ // for values up to 1e11 the fastest is around 3e7
48
+ int const sqrt_limit = 30000000 ;
47
49
48
50
auto primes = sieve(sqrt_limit);
49
51
50
- using ii = pair<ll, int >;
52
+ using ii = pair<ll, ll >;
51
53
52
- map<ii, ll> phi_cache;
54
+ // at least pi(sqrt(sqrt(n)))
55
+ unordered_map<ll, ll> phi_cache[200 ];
53
56
54
57
ll phi (ll x, int a) {
55
- if (phi_cache.count ({x, a})) return phi_cache[{x, a}];
56
-
57
58
if (a == 1 ) {
58
59
return (x+1 )/2 ;
59
60
}
60
61
62
+ if (phi_cache[a].count (x)) {
63
+ return phi_cache[a][x];
64
+ }
65
+
61
66
ll res = phi (x, a-1 ) - phi (x / primes[a-1 ], a-1 );
62
- phi_cache[{x, a} ] = res;
67
+ phi_cache[a][x ] = res;
63
68
64
69
return res;
65
70
}
66
71
67
- map <ll, ll> pi_cache;
72
+ unordered_map <ll, ll> pi_cache;
68
73
69
74
ll pi (ll x) {
70
75
if (pi_cache.count (x)) return pi_cache[x];
@@ -81,7 +86,7 @@ ll pi(ll x) {
81
86
82
87
for (ll i = a+1 ; i <= b; i++) {
83
88
ll w = x / primes[i-1 ];
84
- ll b_i = pi (sqrt (w));
89
+ ll b_i = pi (isqrt (w));
85
90
res -= pi (w);
86
91
87
92
if (i <= c) {
@@ -94,6 +99,7 @@ ll pi(ll x) {
94
99
pi_cache[x] = res;
95
100
return res;
96
101
}
102
+
97
103
int main () {
98
104
ll n;
99
105
cin >> n;
0 commit comments