Cod sursa(job #1073451)

Utilizator danny794Dan Danaila danny794 Data 6 ianuarie 2014 12:49:37
Problema Frac Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.45 kb
#include <cstdio>
#include <cmath>

typedef long long ll;

using namespace std;

ll N, P;
bool p[110000];
ll primes[10460], Pr;
ll dividePrimes[40], D;

void read() {
	freopen( "frac.in", "r", stdin );
	//freopen( "frac.out", "w", stdout );
	scanf("%lld %lld", &N, &P);
}

void precomputePrimes() {
	for(int i = 2; i <= 400; i++)
		if(!p[i]) {
			for(ll j = i*i; j <= 110000; j+=2 * i)
				p[j] = true;
		}

	primes[0] = 2;
	Pr = 1;

	for(int i = 3; i < 110000; i+=2)
		if (!p[i]) {
			primes[Pr] = i;
			Pr++;
		}

}

ll inline divide(ll B, int p) {
	while(!(B % p))
		B /= p;
	return B;
}

void inline getDividePrimes(ll B) {
	D = 0;
	for(int i = 0; i < Pr && primes[i] <= sqrt(B); i++)
		if (B % primes[i] == 0){
			dividePrimes[D] = primes[i];
			D++;
			B = divide(B, primes[i]);
		}

	if ( B > 1 ) {
		dividePrimes[D] = B;
		D++;
	}
}

ll inline getFactor(ll count) {
	ll p = 1;
	for(int i = 0; i < D; i++) {
		if ( count & 1 )
			p *= -1;
		else
			p *= dividePrimes[i];
		count >>= 1;
	}

	return p;
}

ll compute(ll B) {
	ll result = 0;
	ll count = 1 << D;
	while( count ) {
		result += B / getFactor(count);
		count--;
	}

	if( result > 0 )
		return result;
	else
		return -result;
}

void binarySearch(ll l, ll r) {
	ll C = -1;
	ll m;
	while( C != P ) {
		m = (l + r) / 2;
		C = compute(m);

		if ( C < P )
			l = m;
		else
			r = m;
	}

	printf("%lld", m);
}

int main() {
	read();
	precomputePrimes();
	getDividePrimes(N);
	ll r = 1l << 61;
	binarySearch(1, r);
	return 0;
}