Cod sursa(job #2586044)

Utilizator VladTZYVlad Tiganila VladTZY Data 19 martie 2020 17:40:27
Problema Frac Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.82 kb
#include <fstream>
#include <climits>

#define DIVIMAX 15
#define CMAX 200

using namespace std;

ifstream f("frac.in");
ofstream g("frac.out");

long long int n, nr, nrDiv, totalCombinatii;

long long int combinatii[CMAX];
long long int divi[DIVIMAX];

void getDiv(long long int n)
{
    for(int div = 2; div * div <= n; div++)
    {
        if(n % div == 0)
        {
            divi[nrDiv++] = div;

            while(n % div == 0)
                n = n / div;
        }
    }

    if(n > 1)
        divi[nrDiv++] = n;
}

void getCombinations(int k, long long int prod, int ind)
{
    if(k > 0)
    {
        if(k % 2 == 1)
            combinatii[totalCombinatii++] = prod;
        else
            combinatii[totalCombinatii++] = prod * -1;
    }

    for(int i = ind; i < nrDiv; i++)
    {
        prod *= divi[i];

        getCombinations(k + 1, prod, i + 1);

        prod /= divi[i];
    }
}

long long int getNr(long long int n)
{
    long long int rez = n;
    for(int i = 0; i < totalCombinatii; i++)
    {
        if(combinatii[i] > 0)
        {
            long long int nr = n / combinatii[i];
            rez -= nr;
        }
        else
        {
            long long int nr = n / (combinatii[i] * -1);
            rez += nr;
        }
    }
    return rez;
}

int main()
{
    f >> n >> nr;

    getDiv(n);
    getCombinations(0, 1, 0);

    long long int st = 1, dr = LLONG_MAX - 1, poz;

    while(st <= dr)
    {
        long long int mij = (st + dr) / 2;
        long long int val = getNr(mij);

        if(val == nr)
        {
            poz = mij;
            dr = mij - 1;
            continue;
        }

        if(val < nr)
            st = mij + 1;
        else
            dr = mij - 1;
    }

    g << poz;
    return 0;
}