Cod sursa(job #129683)

Utilizator damaDamaschin Mihai dama Data 29 ianuarie 2008 21:23:53
Problema Frac Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.68 kb
#include <stdio.h>

long long n, p, ans, div[32], min, mid, max, sol, nr, s = 1;
int v[110001], prime[100001];

void bkt(int k);
void ciur();

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

    int i;
    long long temp;

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

    temp = n;
    ciur();
    for(i = 1; prime[i] * prime[i] <= n; ++i)
    {
        if(temp % prime[i] == 0)
        {
            div[++div[0]] = prime[i];
        }
        while(temp % prime[i] == 0)
            temp /= prime[i];
    }
    if(temp != 1)
    {
        div[++div[0]] = temp;
    }
    min = 0;
    max = (long long) 1 << 61;

    while(min <= max)
    {
        sol = 0;
        mid = (min + max) / 2;
        bkt(1);
        //printf("%lld %lld\n", mid, sol);
        if(sol < p)
        {
            min = mid + 1;
        }
        else if(sol == p)
        {
            ans = mid;
            max = mid - 1;
        }
        else
        {
            max = mid - 1;
        }
    }

    printf("%lld\n", ans);

    return 0;
}

void bkt(int k)
{
    if(k == div[0] + 1)
    {
        if(nr % 2 == 0)
        {
            sol += mid / s;
        }
        else
        {
            sol -= mid / s;
        }
    }
    else
    {
        bkt(k + 1);
        ++nr;
        s *= div[k];
        bkt(k + 1);
        --nr;
        s /= div[k];
    }
}

void ciur()
{
    int i, j;
    for(i = 2; i <= 110000; ++i)
    {
        if(!v[i])
        {
            prime[++prime[0]] = i;
            for(j = 2 * i; j <= 11000; j += i)
            {
                v[j] = 1;
            }
        }
    }
}