Pagini recente » Cod sursa (job #2529506) | Cod sursa (job #2679272) | Cod sursa (job #500886) | Istoria paginii runda/aaaaaaaaa/clasament | Cod sursa (job #3296655)
#include <fstream>
#include <vector>
#include <bitset>
using namespace std;
const int RMAX = 110000;
const long long VMIN = 1;
const long long VMAX = 1LL << 61;
vector <int> prime;
vector <long long> dp;
void ciurul()
{
///construieste prime = vector cu numerele prime <= 10^6
bitset <RMAX+1> c;
for (int d = 2; d * d <= RMAX; d++)
{
if (!c[d])
{
for (int m = d * d; m <= RMAX; m += d)
{
c[m] = 1;
}
}
}
for (int i = 2; i <= RMAX; i++)
{
if (!c[i])
{
prime.push_back(i);
}
}
}
void desc(long long x)
{
int i = 0, np = (int)prime.size();
while (i < np && (long long)prime[i] * prime[i] <= x)
{
if (x % prime[i] == 0)
{
dp.push_back(prime[i]);
while (x % prime[i] == 0)
{
x /= prime[i];
}
}
i++;
}
if (x != 1)
{
dp.push_back(x);
}
}
long long nr_prime_cu(long long n, long long x)
{
int nd = (int)dp.size();
long long nr = 0;
///generam multimile de indici
///(submultimi ale lui {0, 1,... nd-1})
for (int multime = 0; multime < (1 << nd); multime++)
{
bool aduna = true;
long long prod_dp = 1;
for (int i = 0; i < nd; i++)
{
if (multime & (1 << i))///i apartine multime
{
aduna = (!aduna);
prod_dp *= dp[i];
}
}
if (aduna)
{
nr += n / prod_dp;
}
else
{
nr -= n / prod_dp;
}
}
return nr;
}
int main()
{
ifstream in("frac.in");
ofstream out("frac.out");
ciurul();
long long n, p;
in >> n >> p;
desc(n);
long long st = VMIN, dr = VMAX, rez = dr + 1;
while (st <= dr)
{
long long m = (st + dr) / 2;
if (nr_prime_cu(m, n) >= p)
{
rez = m;
dr = m - 1;
}
else
{
st = m + 1;
}
}
out << rez << "\n";
in.close();
out.close();
return 0;
}