Cod sursa(job #2464668)

Utilizator SergiuS3003Sergiu Stancu Nicolae SergiuS3003 Data 28 septembrie 2019 18:56:38
Problema Frac Scor 40
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.69 kb
#include <iostream>
#include <fstream>
using namespace std;
ifstream f ( "frac.in" );
ofstream g ( "frac.out" );
long long N, P;
long long fact[20];
int v[20], lv;
long long nrprimi;
long long cn;
int semn = -1;
void afis ( int k )
{
    long long p = 1;

    for ( int i = 1; i <= k; i++ )
        p *= fact[v[i]];

    nrprimi = nrprimi + semn * cn / p;
}
bool valid ( int x )
{
    if ( v[x - 1] >= v[x] )
        return 0;

    return 1;
}
void backt ( int x, int k )
{
    if ( x <= k )
        for ( int i = v[x - 1] + 1; i <= lv - k + x; i++ ) ///(*)
        {
            v[x] = i;
            backt ( x + 1, k );
        }
    else
        afis ( k );
}
int main()
{
    f >> N >> P;
    nrprimi = N;

    if ( N == 1 )
    {
        g << P;
        return 0;
    }

    cn = N;

    if ( N % 2 == 0 )
    {
        fact[++lv] = 2;

        while ( N % 2 == 0 )
            N /= 2;
    }

    for ( long long i = 3; i * i <= N; i += 2 )
        if ( N % i == 0 )
        {
            fact[++lv] = i;

            while ( N % i == 0 )
                N /= i;
        }

    if ( N > 1 )
        fact[++lv] = N;

    for ( int i = 1; i <= lv; i++ )
    {
        backt ( 1, i );
        semn = -semn;
    }

    long long rest = P % nrprimi;
    long long cat = P / nrprimi;
    long long contor = 0, i = 0;

    while ( contor < rest )
    {
        i++;
        bool ok = 1;

        for ( int j = 1; j <= lv; j++ )
            if ( i % fact[j] == 0 )
            {
                ok = 0;
                break;
            }

        if ( ok == 1 )
            contor++;
    }

    g << i + cat*cn;
    return 0;
}