Pagini recente » Cod sursa (job #685095) | Profil Marose1928 | Profil CanabizzzLife | Cod sursa (job #2236146) | Cod sursa (job #1727436)
#include <fstream>
#include <vector>
#include <math.h>
//http://www.infoarena.ro/problema/fractii
const char* inFile = "fractii.in";
const char* outFile = "fractii.out";
std::vector<bool> init_primes_sieve(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;
}
}
return sieve;
}
unsigned long long get_sum_totients(int n, const std::vector<bool>& sieve)
{
std::vector<int> primes;
for (int i = 2; i <= n; ++i)
{
if (sieve[i])
{
primes.push_back(i);
}
}
std::vector<int> cached_totients(n + 1, 0);
for (auto k = 2; k <= n; ++k)
{
if (sieve[k])
{
cached_totients[k] = k - 1;
continue;
}
for (auto p : primes)
{
if (p > sqrt(k)) continue;
if (k % p == 0)
{
auto l = k / p;
auto tot_l = cached_totients[l];
if (l % p == 0)
{
tot_l *= p;
}
else
{
tot_l *= p - 1;
}
cached_totients[k] = tot_l;
break;
}
}
}
unsigned long long sum = 0;
for (auto t : cached_totients)
{
sum += t;
}
return sum;
}
unsigned long long compute_num_irred_fractions(int n)
{
if (n == 1) return 1;
auto sieve = init_primes_sieve(n);
auto sum_totients = get_sum_totients(n, sieve);
return 1 + 2 * sum_totients;
}
int main()
{
int n = 0;
{
std::ifstream readFile(inFile);
if (!readFile) return -1;
readFile >> n;
}
auto num = compute_num_irred_fractions(n);
{
std::ofstream writeFile(outFile);
writeFile << num;
}
return 0;
}