Cod sursa(job #1323982)

Utilizator PikachuPikachu Pikachu Data 21 ianuarie 2015 17:54:29
Problema Frac Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.98 kb
#include <cstdio>
#include <cmath>
#include <cstring>

using namespace std;

long long aa, bb;
bool c[1000005];
int cc[1000005];
int f[105];

void ciur() {
    int n = 1000000, lim = 1000;
    c[0] = c[1] = 1;
    cc[0] = 1;
    cc[1] = 2;
    for(int i = 4; i <= n; i += 2)
        c[i] = 1;
    for(int i = 3; i <= lim; i += 2)
        if(!c[i]) {
            for(int j = i * i; j <= n; j += 2 * i)
                c[j] = 1;
        }
    for(int i = 3; i <= n; i += 2) {
        if(!c[i]) {
            ++ cc[0];
            cc[cc[0]] = i;
        }
    }
}

void desc(long long n) {
    int d, e;
    //lim = (int) sqrt((double) n);
    d = 1;
    f[0] = 0;
    while(1LL * cc[d] * cc[d] <= n && n > 1) {
        e = 0;
        while(n % cc[d] == 0) {
            ++ e;
            n /= cc[d];
        }
        if(e != 0) {
            ++ f[0];
            f[f[0]] = cc[d];
        }
        ++ d;
    }
    if(n > 1) {
        ++ f[0];
        f[f[0]] = n;
    }
}

long long sol(long long a, long long b) {
    long long n = 0, cate, prod, m;
    desc(b);
    m = 1 << f[0];

    for(long long i = 1; i < m; ++ i) {
        cate = 0;
        prod = 1;
        for(long long j = 1; j <= f[0]; ++ j) {
            if(i & (1 << (j - 1))) {
                ++ cate;
                prod *= f[j];
            }
        }
        if(cate & 1) {
            n += a / prod;
        } else {
            n -= a / prod;
        }
    }

    return a - n;
}

bool ok(long long med) {
    if(sol(med, aa) >= bb)
        return 1;
    return 0;
}

long long bin(long long st, long long dr) {
    long long med, last = -1;
    while(st <= dr) {
        med = st + (dr - st) / 2;
        if(ok(med)) {
            last = med;
            dr = med - 1;
        } else 
            st = med + 1;
    }
    return last;
}

int main() {
    freopen("frac.in", "r", stdin);
    freopen("frac.out", "w", stdout);

    long long c;
    c = 1LL << 61;
    ciur();
    scanf("%lld%lld", &aa, &bb);
    printf("%lld\n", bin(1, c));

    return 0;
}