Cod sursa(job #1751315)

Utilizator eddie.deaconuDeaconu Stefan-Eduard eddie.deaconu Data 1 septembrie 2016 10:54:56
Problema Frac Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.45 kb
#include <iostream>
#include <fstream>

using namespace std;

long long N, P;

long long divz[13];
int ndiv, nt;

void divizori(long long a)
{
    ndiv = 0;
    if(a % 2 == 0)
    {
        divz[++ndiv] = 2;
        do
        {
            a /= 2;
        }
        while(a % 2 == 0);
    }
    for(int i = 3; 1LL * i * i <= a; i += 2)
        if(a % i == 0)
        {
            divz[++ndiv] = i;
            do
            {
                a /= i;
            }
            while(a % i == 0);
        }
    if(a > 1) divz[++ndiv] = a;
}

long long calcul(long long x)
{
    long long card = 0;
    for(int i = 1; i < nt; i++)
    {
        int p2, nfact = 0;
        long long prod = 1;
        for(int j = 0; (p2 = 1 << j) <= i; j++)
            if(p2 & i)
            {
                prod *= divz[j + 1];
                nfact++;
            }
        long long t = x / prod;
        if(nfact % 2 == 0)
            card -= t;
        else
            card += t;
    }
    return x - card;
}



int main()
{
    ifstream f("frac.in");
    ofstream g("frac.out");
    f >> N >> P;
    divizori(N);
    nt = 1 << ndiv;
    long long st=1LL, dr=1LL<<61, R;
    while(st<=dr)
    {
        long long mij=(st+dr)/2;
        if (calcul(mij)<P)
            st=mij+1;
        else
        {
            R=mij;
            dr=mij-1;
        }
    }
    g<<R;
    f.close();
    g.close();
    return 0;
}