Cod sursa(job #2949146)

Utilizator MihaiCostacheCostache Mihai MihaiCostache Data 29 noiembrie 2022 23:25:00
Problema Frac Scor 40
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.15 kb
#include <fstream>

using namespace std;
ifstream fin("frac.in");
ofstream fout("frac.out");
int a, b, d, p, st, dr, k, sol, prod, nr;
long long int v[30], m[30];
int main()
{
    /// a p-a fractie ireductibila cu numitorul N.
    ///scriem fractiile in ordince crescatoare in fct de numarator si daca o vrem pe a p-a folosim pinex, si vedem al p-lea
    ///nr care este mai mic decat n si prim cu el
    ///daca avem sa zicem numitorul n si un numar x si vrem sa spunem cate numere pana in x sunt prime intre ele cu n
    ///nu putem sa trecem prin toate numerele si rezultatul poate chiar sa depaseasca n, deci nu putem sa iteram prin toti x
    ///putem mai eficient sa facem un p(n, x)
    ///daca avem un y<x => p(n, y)<p(n, x)
    ///daca avem y>x => p(n, y)>p(n, x)
    ///la un moment dat p(n, x) atinge valoarea cautata si putem sa cautam binar
    ///cautam binar
    ///calculam p(n, mid) si daca p(n, mid)<P, atunci crestem stanga
    ///daca p(n, mid)>P, atunci scadem dreapta
    fin>>a>>b;
    p=a;
    d=2;
    while(p!=1 && d*d<=p)
    {
        int exp=0;
        while(p%d==0)
        {
            p/=d;
            exp++;
        }
        if(exp!=0)
        {
            v[++k]=d;
        }
        d++;
    }
    if(p!=1)
    {
        v[++k]=p;
    }
    st=1;
    dr=1e18;
    while(st<=dr)
    {
        int mid=(st+dr)/2;
        for(int i=0; i<=k; i++)
        {
            m[i]=0;
        }
        sol=0;
        while(m[0]==0)
        {
            int cnt=k;
            while(m[cnt]==1 && cnt>0)
            {
                m[cnt]=0;
                cnt--;
            }
            m[cnt]=1;
            if(m[0]==1)break;
            nr=0;
            prod=1;
            for(int i=1; i<=k; i++)
            {
                if(m[i]==1)
                {
                    prod*=v[i];
                    nr++;
                }
            }
            if(nr%2==0)
                sol-=mid/prod;
            else
                sol+=mid/prod;
        }
        if(mid-sol<b)
            st=mid+1;
        else
            dr=mid-1;
    }
    fout<<st;
    return 0;
}