Pagini recente » Cod sursa (job #2216394) | Cod sursa (job #2471721) | Cod sursa (job #1834756) | Cod sursa (job #2938390) | Cod sursa (job #2083262)
#include<bits/stdc++.h>
using namespace std;
ifstream f("frac.in");
ofstream g("frac.out");
long long n,p;
vector<int>v;
//descompune numitorul in factori primi in v
void desc_fact_primi(long long n){
if(n%2==0)v.push_back(2);
while(n%2==0) n/=2;
long long i=3;
while(n>1){
if(n%i==0) v.push_back(i);
while(n%i==0) n/=i;
i+=2;
}
}
//returneaza al x-lea numar care este prim cu n
long long prim(long long x){
long long sol=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;
}
sol+=x/prod*semn;
}
return sol;
}
//cautare binara pentru eficienta
//cauta numarul prim cu n de pe pozitia p
long long cautare_binara(long long x){
long long s=0,d=n-1,last_poz=-1;
while(s<=d){
long long mij=(d-s)/2+s;
long long median=prim(mij);
if(median<p) {
s=mij+1;continue;
}
else if(median>p) {
d=mij-1;continue;
}
last_poz=mij;
d=mij-1;
}
return last_poz;
}
//calculeaza cate numere intre 1 si n sunt prime cu n (secventa farey)
long long nediv(long long x){
for(unsigned int i=0;i<v.size();++i){
x/=v[i];
x*=v[i]-1;
}
return x;
}
int main(){
f>>n>>p;
desc_fact_primi(n);
long long nr_nedivizori=nediv(n);
long long interval;
if(p%nr_nedivizori==0) //daca p este la inceput de interval
{g<<n*p/nr_nedivizori-1<<'\n';return 0;}
interval=p/nr_nedivizori;
p%=nr_nedivizori;
long long rez=cautare_binara(n);
g<<interval*n+rez<<'\n';
}