Cod sursa(job #3292470)

Utilizator yellowGreenFatu Mihai yellowGreen Data 8 aprilie 2025 12:58:02
Problema Frac Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.8 kb
#include <fstream>
#include <vector>
#define int long long
#define eb emplace_back
using namespace std;
ifstream cin("frac.in");
ofstream cout("frac.out");
int n,p,N[120005],q,m;
bool E[120005];
vector<int> divizori,mob;
int check(int k)
{/// cate numere mai mici sau egale cu k au cmmdc 1 cu n
    int ans=0;
    for(int i=1;i<=m;i++)
    {
        ans=ans+(k/divizori[i])*mob[i];
    }
    return ans+k;
}
signed main()
{
    n=120000;
    for(int i=2;i<=n;i++)
        E[i]=1;
    for(int i=2;1LL*i*i<=n;i++)
        if(E[i])
            for(int j=i;1LL*j*i<=n;j++)
                E[i*j]=0;
    for(int i=2;i<=n;i++)
        if(E[i])
            N[++q]=i;
    q--;
    cin>>n>>p;
    divizori.eb(1);
    for(int d=1;d*d<=n;d++)
        if(n%d==0)
        {
            if(d!=1)
                divizori.eb(d);
            if(d!=n/d)
                divizori.eb(n/d);
        }
    m=divizori.size()-1;
    mob.resize(m+5);
    for(int i=1;i<=m;i++)
    {
        int x=divizori[i];
        int d=1,sgn=0,ok=0;
        while(x>1 && d<=q)
        {
            if(N[d]*N[d]>x)
                break;
            if(x%N[d]==0)
            {
                int e=0;
                while(x%N[d]==0) e++,x=x/N[d];
                if(e>1)
                {
                    ok=1;
                    break;
                }
                sgn++;
            }
            d++;
        }
        if(ok==1) continue;
        if(x!=1) sgn++;
        sgn=sgn%2;
        if(sgn==0) mob[i]=1;
        else mob[i]=-1;
    }
    int st=1,dr=(1LL<<62),ans=0;
    while(st<=dr)
    {
        int mij=(st+dr)>>1;
        if(check(mij)>=p)
        {
            ans=mij;
            dr=mij-1;
        }
        else st=mij+1;
    }
    cout<<ans;
    return 0;
}