Cod sursa(job #1283248)

Utilizator scipianusFMI Ciprian Olariu scipianus Data 5 decembrie 2014 14:04:57
Problema Frac Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.42 kb
#include <fstream>
using namespace std;
long long n, P, fact[30];
int prime[30100], nrp, nrf;
bool ciur[110100];

inline long long Count(long long m)
{
	int i, conf, lim = (1 << nrf), semn;
	long long rez = m, now;
	for(conf = 1; conf < lim; ++conf)
	{
		now = m;
		semn = 0;
		for(i = 0; i < nrf; ++i)
		{
			if(conf & (1 << i))
			{
				now /= fact[i];
				semn++;
			}
		}
		if(semn % 2 == 0)
			semn = 1;
		else
			semn = -1;
		rez += 1LL * semn * now;
	}
	return rez;
}

inline long long CautareBinara()
{
	long long st, dr, mij, rez;
	st = 1LL;
	dr = (1LL << 61LL);
	rez = dr;
	while(st <= dr)
	{
		mij = st + (dr - st) / 2LL;
		if(Count(mij) >= P)
		{
			rez = mij;
			dr = mij - 1LL;
		}
		else
			st = mij + 1LL;
	}
	return rez;
}

int main()
{
	int i, j;
	ifstream fin("frac.in");
	fin >> n >> P;
	fin.close();
	
	prime[++nrp] = 2;
	for(i = 3; i < 110000; i += 2)
	{
		if(!ciur[i])
		{
			prime[++nrp] = i;
			if(i <= 2000)
				for(j = i * i; j < 110000; j += 2 * i)
					ciur[j] = true;
		}
	}
	
	long long aux = n;
	i = 1;
	while(1LL * prime[i] * prime[i] <= aux)
	{
		if(aux % (1LL * prime[i]) == 0LL)
		{
			fact[nrf++] = 1LL * prime[i];
			while(aux % (1LL * prime[i]) == 0LL)
				aux /= (1LL * prime[i]);
		}
		i++;
	}
	if(aux > 1LL)
		fact[nrf++] = aux;
	
	ofstream fout("frac.out");
	fout << CautareBinara() << "\n";
	fout.close();
	return 0;
}