Cod sursa(job #1727405)

Utilizator arenauserIon Ion arenauser Data 10 iulie 2016 18:28:51
Problema Fractii Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.54 kb
#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<std::vector<int>> get_factorizations(int n)
{
    std::vector<std::vector<int>> sieve(n + 1);

    auto max_prime_check = n/2 + 1;

    for (int p = 2; p <= max_prime_check; ++p)
    {
        if (!sieve[p].empty()) continue;

        auto multiple_p = 2 * p;

        while (multiple_p <= n)
        {
            sieve[multiple_p].push_back(p);
            multiple_p += p;
        }
    }

    return sieve;
}

int get_totient_value(int k, const std::vector<int>& k_factors)
{
    if (k_factors.empty()) return k - 1;

    //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 : k_factors)
    {
        prod_p *= p;
        prod_p_minus *= (p - 1);
    }

    return  (k / prod_p) * (prod_p_minus);
}

int compute_num_irred_fractions(int n)
{
    auto factorizations = get_factorizations(n);

    int result = 1;

    for (int i = 2; i <= n; ++i)
    {
        result += 2 * get_totient_value(i, factorizations[i]);
    }

    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;
}