Cod sursa(job #1117031)

Utilizator smaraldaSmaranda Dinu smaralda Data 22 februarie 2014 23:17:01
Problema Frac Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.83 kb
#include<stdio.h>
#include<math.h>

const long long NMAX = 12e9;

long long n, p, subm[6000000];

long long count (long long x) {
    int i;
    long long ans = x;

    for(i = 1; i <= subm[0]; i++)
        ans += x / subm[i];

    return ans;
}

long long bs (long long left, long long right) {
    long long mid, last;

    while(left <= right) {
        mid = right + (left - right) / 2;
        if(count(mid) >= p)
            last = mid,
            right = mid - 1;
        else
            left = mid + 1;
    }
    return last;
}

void fact () {
    long long p, bit, cnt, d, lim, s, cn, f[30];
    bool sieve[100010];
    int prime[100000], i, j, e;

    cn = 1e5 + 5; lim = sqrt(cn);
    sieve[0] = sieve[1] = 1;
    for(i = 4; i <= cn; i += 2)
        sieve[i] = 1;
    for(i = 3; i <= lim; i += 2)
        if(!sieve[i])
            for(j = i * i; j <= cn; j += 2 * i)
                sieve[j] = 1;
    sieve[2] = 0;
    for(i = 1; i <= lim; i++)
        if(!sieve[i])
            prime[++prime[0]] = i;

    d = 1;
    f[0] = 0;
    cn = n;
    lim = sqrt(cn);
    while(cn > 1 && prime[d] <= lim) {
        e = 0;
        while(cn % prime[d] == 0)
            e = 1,
            cn /= prime[d];
        if(e)
            f[++f[0]] = prime[d];
        ++d;
    }
    if(cn > 1)
        f[++f[0]] = cn;

    for(s = 1; s < (1 << f[0]); s++) {
        cnt = 0;
        p = 1;
        for(bit = 0; bit < f[0]; bit++)
            if(s & (1 << bit))
                ++cnt,
                p *= f[bit + 1];
        if(cnt % 2 == 1)
            p *= -1;
        subm[++subm[0]] = p;
    }
}

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

    scanf("%lld%lld",&n,&p);

    fact();
    printf("%lld\n",bs(1, (long long)1 << 61));
    return 0;
}