Cod sursa(job #1802628)

Utilizator SlevySlevoaca Stefan-Gabriel Slevy Data 10 noiembrie 2016 15:30:15
Problema Frac Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.6 kb
#include <iostream>
#include <fstream>
#include <cmath>
#define NMAX 109600

using namespace std;

ifstream in("frac.in");
ofstream out("frac.out");

long long int n, p;
bool prime[NMAX];
long long int nr_p[NMAX];
long long int fact[30];
int k = 0, r = 0;

void ciur()
{
	long long int lim = sqrt(12000000000LL);
	for (long long int i = 3; i * i <= lim; i += 2)
	{
		if (!prime[i])
		{
			for (long long int j = i * i; j <= lim; j += (2 * i))
				prime[j] = true;
		}
	}
	nr_p[++k] = 2;
	for (long long int i = 3; i <= lim; i += 2)
		if (!prime[i])
			nr_p[++k] = i;
}

void descomp()
{
	int poz = 1;
	while (nr_p[poz] * nr_p[poz] <= n)
	{
		if (n % nr_p[poz] == 0)
		{
			while (n % nr_p[poz] == 0)
				n /= nr_p[poz];
			fact[++r] = nr_p[poz];
		}
		poz++;
		if (poz > k)
			break;
	}
	if (n != 1)
		fact[++r] = n;
}

long long int binara()
{
	long long int st = 1, dr = (1LL << 61);
	long long int mij, rez;
	long long int prod;
	long long int nr;
	while (st < dr)
	{
		mij = st + (dr - st) / 2;
		rez = mij;
		for (long long int i = 1; i < (1LL << r); i++)
		{
			prod = 1;
			nr = 0;
			for (long long int j = 0; (1LL << j) <= i; j++)
				if (i & (1LL << j))
				{
					prod *= fact[j + 1];
					nr++;
				}
			if (nr & 1LL)
				rez -= (mij / prod);
			else
				rez += (mij / prod);
		}
		if (rez < p)
			st = mij + 1;
		else
			if (rez > p)
				dr = mij - 1;
			else
				if (rez == p)
					dr = mij;
	}
	return st;
}

int main()
{
	in >> n >> p;
	in.close();
	ciur();
	descomp();
	out << binara() << "\n";
	out.close();
	return 0;
}