Cod sursa(job #265430)

Utilizator silvia_the_bestSilvia Pripoae silvia_the_best Data 23 februarie 2009 21:29:40
Problema Frac Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.45 kb
#include <cstdio>
#define FIN "frac.in"
#define FOUT "frac.out"
#define X 111100
#define MAX 100000000
#define M 100
long long n,p,d[M],v[X],nrd,m,rez,r;
void read()
{
	freopen(FIN,"r",stdin);
	scanf("%lld %lld", &n, &p);
}
void div()
{
	int i,j,k = n;
	v[0] = v[1] = 1;
	for (i = 4; 1LL * i * i < n; i += 2)
		v[i] = 1;
	for (i = 3; 1LL * i * i < n; i += 2)
		if (!v[i]){
			j = 2 * i;
			while (1LL * j * j < n)
			{
				v[j] = 1;
				j += i;
			}
		}
	for (i = 2; 1LL * i * i <= k; ++i)
		if (!v[i] && n % i == 0)
		{
			d[++nrd] = i;
			while (n % i == 0)
				n /= i;
		}
	if (n > 1)
	{
		++nrd;
		d[nrd] = n;
	}
}
void calc(int x,int p,int l)
{
	++l;
	int i;
	if (l % 2 == 1)
		rez += m / (p * d[x]);
	else
		rez -= m / (p * d[x]);
	for (i = x + 1; i <= nrd; ++i)
		calc(i, p * d[x], l);
}
void solve()
{
	int i;
	long long f = 1,l = MAX * MAX * 1LL,ok,c;
	div();
	while (f <= l)
	{
		m = (f + l) / 2LL;
		c = 0; rez = 0;
		for (i = 1; i <= nrd; ++i)
		{
			rez = 0;
			calc(i,1,0);
			c +=rez;
		}
		ok = 0;
		for (i = 1; i <= nrd && ok == 0; ++i)
			if (m % d[i] == 0)
				ok = 1;
		if (m - c == p && !ok)
			break;
        else if (m - c == p)
            l -= 2;
		if (m - c < p)
			f = m + 1;
		else if (m - c > p)
			l = m;
	}
	if (r != l)
		r = m;
	else
		r = p;
}
void write()
{
	freopen(FOUT,"w",stdout);
	printf("%lld\n", r);
}
int main()
{
	read();
	solve();
	write();
}