Pagini recente » Cod sursa (job #1812724) | Cod sursa (job #468235) | Cod sursa (job #2770597) | Cod sursa (job #182243) | Cod sursa (job #627126)
Cod sursa(job #627126)
#include <stdio.h>
#include <math.h>
#include <vector>
#define dim 10000002 //square root of 10^14;
#define max_u64 0xffffffffffffffff //max value for unsigned 64 bit
using namespace std;
typedef unsigned long long uint64;
typedef unsigned int uint32;
uint64 n,p,rez;
bool noprnr[dim];
vector <uint64> fprim;
vector <uint32> prim;
vector <uint32> stack;
vector <uint64> num;
void get_prim()
{
uint32 i,j;
noprnr[0]=true;
noprnr[1]=true;
prim.push_back(2);
uint32 sq = sqrt(n) + 1;
for (i=3;i<sq;i+=2)
{
if (noprnr[i]==false)
{
prim.push_back(i);
for(j=2*i;j<sq;j+=i)
noprnr[j]=true;
}
noprnr[i+1]=false;
}
}
void get_fprim()
{
uint32 i;
for (i=0;((i<prim.size())&(n>1));i++)
{
if (n%prim[i]==0)//prime factor
{
fprim.push_back(prim[i]);
while (n%prim[i]==0)//eliminate prim[i]
n/=prim[i];
}
}
if (n>1)//p is prime
fprim.push_back(n);
}
void fill(int level, int index)
{
uint32 i;
for (i=index;i<fprim.size();i++)
{
if (level==0)
stack.push_back(fprim[i]);
else
stack.push_back(fprim[i]*stack[level-1]);
num.push_back(stack[level]);
fill(level+1,i+1);
stack.pop_back();
}
}
void calculate(uint64 x)
{
rez=0;
uint32 i;
for (i=0;i<num.size();i++)
if(i%2==0)
rez+=x/num[i];
else
rez-=x/num[i];
rez = x - rez;
}
uint64 search()
{
uint64 l=0,m,r=max_u64;
get_prim();
get_fprim();
prim.clear();
fill(0,0);
fprim.clear();
while (l<=r)
{
m = (l+r)>>1;
calculate(m);
if (rez == p)
{
do
{
m--;
calculate(m);
}while (rez==p);
return m+1;
}
else
{
if (rez>p)//have to reduce upper bound;
r=m+1;
else //have to increase lower bound;
l=m-1;
}
}
return -1;
}
int main()
{
freopen("frac.in","r",stdin);
freopen("frac.out","w",stdout);
scanf("%lld %lld",&n,&p);
printf("%lld\n",search());
return 0;
}