Pagini recente » Cod sursa (job #1819303) | Cod sursa (job #2386573) | Cod sursa (job #2442994) | Cod sursa (job #2325354) | Cod sursa (job #1727171)
#include <fstream>
#include <vector>
//http://www.infoarena.ro/problema/fractii
const char* inFile = "fractii.in";
const char* outFile = "fractii.out";
std::vector<int> init_primes(int n)
{
std::vector<bool> sieve (n + 1, true);
auto max_prime_check = int(sqrt(n));
for (int p = 2; p <= max_prime_check; ++p)
{
if (!sieve[p]) continue;
auto multiple_p = 2 * p;
while (multiple_p <= n)
{
sieve[multiple_p] = false;
multiple_p += p;
}
}
std::vector<int> primes;
primes.reserve(int(sqrt(n) / 2));
for (int i = 2; i <= n; ++i)
{
if (sieve[i])
{
primes.push_back(i);
}
}
return primes;
}
int euler_totient(int k, const std::vector<int>& cached_primes)
{
//totient = k * prod(1 - 1/p), for all p prime which divide k
int prod_p_minus = 1;
int prod_p = 1;
for (auto p : cached_primes)
{
if (p > k) break;
if (k % p == 0)
{
prod_p *= p;
prod_p_minus *= (p - 1);
}
}
return (k / prod_p) * (prod_p_minus);
}
int compute_num_irred_fractions(int n)
{
auto smaller_primes = init_primes(n);
int result = 1;
for (int i = 2; i <= n; ++i)
{
result += 2 * euler_totient(i, smaller_primes);
}
return result;
}
int main()
{
int n = 0;
{
std::ifstream readFile(inFile);
if (!readFile) return -1;
readFile >> n;
}
int num = compute_num_irred_fractions(n);
{
std::ofstream writeFile(outFile);
writeFile << num;
}
return 0;
}