Cod sursa(job #2107133)

Utilizator PondorastiAlex Turcanu Pondorasti Data 16 ianuarie 2018 19:48:12
Problema Frac Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.61 kb
#include <fstream>
#include <vector>

#define i64 long long

using namespace std;

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

i64 number, pos, ans;
vector<i64> divisors, pinex;

void descompunere() {
    if (number % 2 == 0) {
        while (number % 2 == 0) { number >>= 1; }
        divisors.push_back(2);
    }
    for (i64 d = 3; d * d <= number; d += 2) {
        if (number % d == 0) {
            while (number % d == 0) { number /= d; }
            divisors.push_back(d);
        }
    }
    if (number > 1) { divisors.push_back(number); }
}

void precomputePinex() {
    for (i64 i = 1; i < (1 << divisors.size()); ++i) {
        i64 semn = 0, produs = 1;
        for (i64 j = 0; j < divisors.size(); ++j) {
            if (i & (1 << j)) {
                ++semn;
                produs *= divisors[j];
            }
        }
        if (semn % 2 == 0) {
            pinex.push_back(-1 * produs);
        } else {
            pinex.push_back(produs);
        }
    }
}

i64 doPinexFor(i64 number) {
    i64 answer = number;
    for (auto it: pinex) {
        answer -= number / it;
    }
    return answer;
}



void binarySearch() {
    i64 left = 1, right = (1LL << 61), middle, index;
    while (left <= right) {
        middle = (left + right) / 2;
        index = doPinexFor(middle);
        if (index >= pos) {
            right = middle - 1;
            if (index == pos) {
                ans = middle;
            }
        } else {
            left = middle + 1;

        }
    }
}

int main() {
    in >> number >> pos;
    descompunere();
    precomputePinex();
    binarySearch();
    out << ans << "\n";
    return 0;
}