Cod sursa(job #485173)

Utilizator Addy.Adrian Draghici Addy. Data 17 septembrie 2010 14:50:47
Problema Frac Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.19 kb
#include <cstdio>

const long long KMAX = 100000000000000LL;
const int FMAX = 200000;
const int PMAX = 200000;

long long D[PMAX], P[PMAX], Q[FMAX], QF[FMAX], n, m, i, j, k, p, u, mid, sol;

long long f (long long x) {
	
	long long i, u, y, nr, NQ;
	
	Q[0] = 1, NQ = 0, nr = x;
	for (i = 1; D[i] <= x && i <= D[0]; i++) {
		u = NQ;
		for (j = 0; j <= u; j++) {
			y = Q[j] * D[i];
			if (y <= x) {
				NQ++, Q[NQ] = y, QF[NQ] = QF[j] + 1;
				if (QF[NQ] % 2)
					nr -= x / Q[NQ];
				else
					nr += x / Q[NQ];
			}
		}
	}
	
	return nr;
}

int main () {
	
	freopen ("frac.in", "r", stdin);
	freopen ("frac.out", "w", stdout);
	
	scanf ("%lld %lld", &n, &k);
	
	for (i = 2; i * i <= n; i++)
		if (!P[i]) {
			P[++P[0]] = i;
			for (j = 2 * i; j * j <= n; j += i)
				P[j] = 1;
		}
	
	m = n;
	for (i = 1; P[i] * P[i] <= n && i <= P[0] && m != 1; i++) {
		j = P[i];
		
		if (m % j == 0) {
			D[++D[0]] = j;
			while (m % j == 0)
				m /= j;
		}
	}
	if (m != 1)
		D[++D[0]] = m;
	
	p = 1, u = KMAX;
	while (p <= u) {
		mid = (u - p) / 2 + p;
		if (f (mid) >= k)
			u = mid - 1, sol = mid;
		else
			p = mid + 1;
	}
	
	printf ("%lld", sol);
	
	return 0;
}