Pagini recente » Cod sursa (job #1513024) | Cod sursa (job #1564600) | Cod sursa (job #1169642) | Cod sursa (job #2513191) | Cod sursa (job #1562075)
#include <stdio.h>
#define Nadejde 20
#define ll long long
ll int N, K, M, count;
int size, div[Nadejde];
/** Obtine divizorii lui "x". **/
void getDiv(ll int x) {
if (x % 2 == 0) {
div[size++] = 2;
x /= (x & -x);
}
int i;
for (i = 3; i * i <= x; i += 2) {
if (x % i == 0) {
div[size++] = i;
do {
x /= i;
} while (x % i == 0);
}
}
if (x != 1) {
div[size++] = x;
}
}
/** Principiul includerii si al excluderii. **/
void bkt(int level, ll int x, int card) {
if (x > M) {
return;
}
if (level == size) {
return;
}
/* Nu bagam in seama divizorul curent. */
bkt(level + 1, x, card);
/* Il bagam in seama. */
card++;
x = (ll)x * div[level];
if (card & 1) {
count += M / x;
} else {
count -= M / x;
}
bkt(level + 1, x, card);
}
/** Probeaza valorea "M". **/
ll int try() {
count = 0;
bkt(0, 1, 0);
return M - count;
}
/** Cauta binar a "K"-a fractie. **/
ll int bSearch(ll int lo, ll int hi) {
while (hi - lo > 1) {
M = (lo + hi) >> 1;
if (try() >= K) {
hi = M;
} else {
lo = M;
}
}
return hi;
}
int main(void) {
FILE *f = fopen("frac.in", "r");
/* Citirea datelor. */
fscanf(f, "%lld %lld", &N, &K);
fclose(f);
/* Da-mi divizorii lui "N". */
getDiv(N);
/* Calcularea solutiei si afisarea ei. */
freopen("frac.out", "w", stdout);
fprintf(stdout, "%lld\n", bSearch(0, ((ll)1LL << 61) + 1));
fclose(stdout);
/// Multumim Doamne!
puts("Doamne ajuta!");
return 0;
}