Cod sursa(job #1745582)

Utilizator Y.MalmsteenB.P.M. Y.Malmsteen Data 22 august 2016 11:42:36
Problema Frac Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.68 kb
#include <iostream>
#include <fstream>

using namespace std;

//const long long int PMAX = 100000000000000LL;
//const long long int NMAX = 12000000000LL;

long long int N, P; //Datele de intrare
long long int R; //Rezultatul problemei

long long int divp[20];
int nrd; //divizorii primi ai lui N
int nt;

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

void divizorip(long long int x)
{
    nrd = 0;
    if(x % 2 == 0)
    {
        divp[++nrd] = 2;
        do
        {
            x /= 2;
        }
        while(x % 2 == 0);
    }
    for(long long int i = 3; i * i <= x; i += 2)
        if(x % i == 0)
        {
            divp[++nrd] = i;
            do
            {
                x /= i;
            }
            while(x % i == 0);
        }
    if(x > 1) divp[++nrd] = x;
}

long long int calcul(long long int x)
{
    long long int rez = x;
    //int nt = 1 << nrd; //il declaram global si facem calculul in main()
    for(int i = 1; i < nt; i++)
    {
        long long int prod = 1;
        for(int j = 0, p2; (p2 = 1 << j) <= i; j++)
        {
            if(i & p2)
                prod *= -divp[j + 1];
        }
        rez += x / prod;
    }
    return rez;
}

int main()
{
    long long N, P;
    f >> N >> P;
    divizorip(N);
    nt = 1 << nrd;
    long long int p = 1;
    long long int u = 1LL << 61; //Se garanteaza ca rezultatul nu depaseste 2^61
    while(p <= u)
    {
        long long int m = (p + u) / 2;
        if(calcul(m) < P)
            p = m + 1;
        else
        {
            R = m;
            u = m - 1;
        }
    }
    g << R << endl;
    f.close();
    g.close();
    return 0;
}