Pagini recente » Borderou de evaluare (job #1249721) | Cod sursa (job #540979) | Monitorul de evaluare | Monitorul de evaluare | Cod sursa (job #3342437)
#include <bits/stdc++.h>
using namespace std;
ifstream fin ("frac.in");
ofstream fout("frac.out");
struct info
{
long long int inm;
bool type;
};
long long int red = 0;
vector<info> rinm;
void catiReductibili(vector<long long int>& factprimi, long long int x, int depth, long long int inm, int index)
{
if(index > factprimi.size())
{
return;
}
for(int i = index; i < factprimi.size(); i++)
{
catiReductibili(factprimi, x, depth + 1, inm * factprimi[i], i + 1);
}
if(depth % 2 == 1)
{
red += x / inm;
rinm.push_back({inm, depth % 2});
}
else if(depth != 0)
{
red -= x / inm;
rinm.push_back({inm, depth % 2});
}
}
vector<long long int> factprimi;
int main()
{
long long int numi, k;
fin >> numi >> k;
if(numi == 1)
{
fout << k;
return 0;
}
int lim = sqrt(numi) + 1;
long long int x = numi;
long long int d = 2;
while(x > 1)
{
long long int pw = 0;
while(x % d == 0)
{
x /= d;
pw++;
}
if(pw)
factprimi.push_back(d);
d++;
if(1ll * d * d > x && x != 1)
{
factprimi.push_back(x);
x = 1;
}
}
catiReductibili(factprimi, numi, 0, 1, 0);
long long int tired = numi - red;
long long int ans = ((k - 1) / tired) * numi;
k = (k - 1) % tired + 1;
long long int l = 0, r = numi - 1, best = 0;
while(l <= r)
{
long long int mid = (l + r) / 2;
long long int curr = 0;
for(int i = 0; i < rinm.size(); i++)
{
if(rinm[i].type)
{
curr += mid / rinm[i].inm;
}
else
{
curr -= mid / rinm[i].inm;
}
}
curr = mid - curr;
if(curr >= k)
{
best = mid;
r = mid - 1;
}
else
{
l = mid + 1;
}
}
fout << best + ans;
return 0;
}