Pagini recente » Cod sursa (job #165391) | Cod sursa (job #2300190) | Cod sursa (job #514271) | Cod sursa (job #324937) | Cod sursa (job #2949146)
#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;
}