Cod sursa(job #547255)

Utilizator perticas_catalinperticas catalin perticas_catalin Data 6 martie 2011 03:12:13
Problema Frac Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.07 kb
#include <iostream>
#include <string>
#include <cmath>

using namespace std;

#define NM 105
#define EPS 0.0000000001
#define PMAX 1000000

long long N, P;

long long Nprimes[NM], cans, llimit;
int primes[PMAX + 1];

bool isprime[PMAX+1];

void back (int pas, long long div, int cate)
{
	if (pas == Nprimes[0] + 1)
	{
		if (cate == 0) return ;
		cans += (cate % 2 ? -llimit/div : llimit/div);
		return ;
	}	
	
	back (pas + 1, div * Nprimes[pas], cate + 1);
	back (pas + 1, div, cate);
}

long long how_many (long long limit)
{
	cans = llimit = limit;
	back (1, 1, 0);
	
	//printf ("HMHM %I64d %I64d\n", limit, cans);
	
	return cans;
}	

void find_prime_factors()
{
	long long cN = N;
	int ind = 1, sq = (int)sqrt((long double)N);
	
	while (ind <= primes[0] && primes[ind] <= sq && cN != 1)
	{
		if (cN % primes[ind]) 
		{
			++ind;
			continue;
		}
		Nprimes[++Nprimes[0]] = primes[ind];
		while (cN % primes[ind] == 0) cN /= primes[ind];  
		++ind;
	}	
	if (cN != 1) Nprimes[++Nprimes[0]] = cN;
}

void find_primes()
{
	for (int i = 2; i <= PMAX; ++i) isprime[i] = true;
	
	for (int i = 2; i <= PMAX; ++i)
		if (isprime[i])
		{
			primes[++primes[0]] = i;
			for (int j = 2*i; j <= PMAX; j += i) isprime[j] = false;
		}
}

long long solve()
{
	long long st = 1, dr = (1LL<<61);
	
	while (st < dr)
	{
		//printf ("S si D -> %I64d %I64d\n", st, dr);
		
		long long mij = (st + dr)/2;
		
		long long ld = how_many (mij);
		long long ls = how_many (mij-1);
		
		//printf ("%I64d %I64d %I64d\n", mij, ls, ld);
		
		if (P <= ls) dr = mij - 1;
		if (P > ld) st = mij + 1;
		
		if (ls < P && P <= ld)
		{
			st = dr = mij;
			break;
		}	
	}	
	
	return st;
}

int main()
{
	freopen ("frac.in", "r", stdin);
	freopen ("frac.out", "w", stdout);
	
	find_primes();
	
	scanf ("%lld %lld", &N, &P);	
	
	//printf ("%lld\n", N);
	
	find_prime_factors();
	
	/*
	for (int i = 1; i <= Nprimes[0]; ++i) printf ("%lld ", Nprimes[i]);
	printf ("\n");
	*/
	
	long long ans = solve();
	
	printf ("%lld", ans);
	
	return 0;
}