Pagini recente » Monitorul de evaluare | Cod sursa (job #1638153) | Cod sursa (job #1345349) | Monitorul de evaluare | Cod sursa (job #3347506)
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("frac.in");
ofstream fout("frac.out");
long long n, p, phi;
vector<long long> f;
void get_f(long long x) {
long long d = 2;
long long temp = x;
phi = x;
while (d * d <= temp) {
if (temp % d == 0) {
f.push_back(d);
phi = phi / d * (d - 1);
while (temp % d == 0) temp /= d;
}
d++;
}
if (temp > 1) {
f.push_back(temp);
phi = phi / temp * (temp - 1);
}
}
long long count_rel(long long m) {
long long cnt = 0;
int sz = f.size();
for (int i = 1; i < (1 << sz); ++i) {
long long prod = 1;
int bits = 0;
for (int j = 0; j < sz; ++j) {
if ((i >> j) & 1) {
prod *= f[j];
bits++;
}
}
if (bits % 2 == 1) cnt += m / prod;
else cnt -= m / prod;
}
return m - cnt;
}
int main() {
fin >> n >> p;
if (n == 1) {
fout << p << "\n";
return 0;
}
get_f(n);
long long cycles = (p - 1) / phi;
p = (p - 1) % phi + 1;
long long st = 1, dr = n, ans = 0;
while (st <= dr) {
long long mid = st + (dr - st) / 2;
if (count_rel(mid) >= p) {
ans = mid;
dr = mid - 1;
} else {
st = mid + 1;
}
}
fout << cycles * n + ans << "\n";
return 0;
}