106 lines
2.3 KiB
C++
106 lines
2.3 KiB
C++
/* Totient maximum
|
|
|
|
Euler's Totient function, φ(n) [sometimes called the phi function], is used to determine the number of numbers less than n which are relatively prime to n. For example, as 1, 2, 4, 5, 7, and 8, are all less than nine and relatively prime to nine, φ(9)=6.
|
|
|
|
It can be seen that n=6 produces a maximum n/φ(n) for n ≤ 10.
|
|
|
|
Find the value of n ≤ 1,000,000 for which n/φ(n) is a maximum.
|
|
|
|
*/
|
|
|
|
#include <bits/stdc++.h>
|
|
|
|
using namespace std;
|
|
|
|
const int MAX = 1000000;
|
|
|
|
vector<int> sieve(int n){
|
|
vector<bool> numbers(n+1, true);
|
|
vector<int> result;
|
|
|
|
int i = 2;
|
|
while(i <= n){
|
|
if(numbers[i]){
|
|
result.push_back(i);
|
|
|
|
int j = 2 * i;
|
|
while(j <= n){
|
|
numbers[j] = false;
|
|
j += i;
|
|
}
|
|
}
|
|
++i;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
vector<int> prime_terms(int n){
|
|
vector<int> result;
|
|
|
|
if(n % 2 == 0){
|
|
result.push_back(2);
|
|
|
|
while(n % 2 == 0){
|
|
n /= 2;
|
|
}
|
|
}
|
|
|
|
for(int i = 3; i <= sqrt(n); i += 2){
|
|
if(n % i == 0){
|
|
result.push_back(i);
|
|
|
|
while(n % i == 0){
|
|
n /= i;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(n > 2){
|
|
result.push_back(n);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
int main(){
|
|
|
|
cout << "Hello this is Patrick" << endl;
|
|
auto start = chrono::high_resolution_clock::now();
|
|
|
|
vector<float> n_phi(MAX + 1, 0);
|
|
auto primes = sieve(MAX);
|
|
|
|
for(auto p : primes){
|
|
n_phi[p] = 1 + 1 / ((float)p - 1);
|
|
}
|
|
|
|
int n_max = 0;
|
|
float n_phi_max = 0;
|
|
|
|
for(size_t i = 2; i < n_phi.size(); ++i){
|
|
if(n_phi[i] == 0){
|
|
auto terms = prime_terms(i);
|
|
float acc = 1;
|
|
|
|
for(int t : terms){
|
|
acc *= n_phi[t];
|
|
}
|
|
n_phi[i] = acc;
|
|
|
|
if(n_phi_max < acc){
|
|
n_max = i;
|
|
n_phi_max = acc;
|
|
}
|
|
}
|
|
|
|
// cout << i << " " << n_phi[i] << endl;
|
|
}
|
|
|
|
cout << n_max << endl;
|
|
|
|
auto duration = chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start);
|
|
cout << (float)duration.count()/1000 << endl;
|
|
return 0;
|
|
}
|