Cod sursa(job #2067999)

Utilizator ScarymovieMocanu Alexandru Scarymovie Data 17 noiembrie 2017 01:20:09
Problema Frac Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.66 kb
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
long long N,P;
vector<int> v;
void factorizeaza(long long n)
{
    if(n%2==0)
    {
        v.push_back(2);
        do
        {
            n/=2;
        }
        while(n%2==0);
    }
    for(int i=3; n>1; i+=2)
        if(n%i==0)
        {
            v.push_back(i);
            do
            {
                n/=i;
            }
            while(n%i==0);
        }
}
long long phi(long long x)
{
    for(unsigned int i=0;i<v.size();++i)
    {
        x/=v[i];
        x*=v[i]-1;
    }
    return x;
}
long long PrimN(long long x)
{
    long long solutie=0;
    for(int i=0;i<(1<<v.size());++i)
        {
            long long prod=1,semn=1;
            for(int j=0;j<v.size();++j)
                if(i&(1<<j))
                    {
                        prod*=v[j];
                        semn*=-1;
                    }
            solutie+=x/prod*semn;
        }
    return solutie;
}
long long cautbin(long long x)
{
    long long st=0,dr=N-1,LastApp=-1;
    while(st<=dr)
    {
        long long mij=(dr-st)/2+st;
        long long Intermediate=PrimN(mij);
        if(Intermediate<P) {st=mij+1;continue;}
        if(Intermediate>P) {dr=mij-1;continue;}
        LastApp=mij;
        dr=mij-1;
    }
    return LastApp;
}
int main()
{
    ifstream f("frac.in");
    ofstream g("frac.out");
    f>>N>>P;
    factorizeaza(N);
    long long OrdN=phi(N);
    long long Interval;
    if(P%OrdN==0)
        {g<<N*P/OrdN-1<<'\n';return 0;}
    Interval=P/OrdN;
    P%=OrdN;
    long long rez=cautbin(P);
    g<<Interval*N+rez<<'\n';
    return 0;
}