Cod sursa(job #1345134)

Utilizator pepsiM4A1Ozturk Arif pepsiM4A1 Data 17 februarie 2015 12:11:06
Problema Frac Scor 100
Compilator cpp Status done
Runda prega_rav_1 Marime 1.74 kb
#include <stdio.h>
#define LL long long int
#define inf 230584300921364023LL
LL n, p, st = 1LL, dr = inf, mij, rez;
int div[23], size, arr[23], temp;
LL gcd(LL a, LL b)
{
          if(a == 0) return b;
          return gcd(b%a, a);
}
LL vef()
{
    LL prod = 1;
    for(int i = 1; i<= temp; i++) prod*=div[arr[i]-1];
    return mij/prod;
}
LL comb(int len, int pos)
{
    LL rez= 0;
    if(pos == len+1) return vef();
    for(int i = arr[pos-1]+1; i<=size; i++)
    {
        arr[pos] = i;
        rez+= comb(len, pos+1);
    }
    return rez;
}
void fp()
{
    LL temp2 = n;
    size = 0;
    if(temp2%2 == 0)
    {
        div[size] = 2;
        size++;
        while(!(temp2%2))
        {
            temp2/=2;
        }
    }
    for(int i = 3; 1LL*i*i <= temp2 && temp2 > 1LL; i+=2)
    {
        if(temp2%i == 0)
        {
            div[size] = i;
            size++;
            while(!(temp2%i))
            {
                temp2/=i;
            }
        }
    }
    if(temp2 > 1)
    {
        div[size] = temp2;
        size++;
    }
}
FILE *fin, *fout;
int main()
{
    fin = freopen("frac.in", "r", stdin);
    fout = freopen("frac.out", "w", stdout);
    scanf("%lld%lld", &n, &p);
    fp();
    for( ; ; )
    {
        mij = (st+dr)/2;
        rez = mij;
        for(int i = 1; i<= size; i++)
        {
            temp = i;
            if(i%2) rez -= comb(i, 1);
            else rez += comb(i, 1);
        }
        if(rez == p)
        {
            if(gcd(mij, n) > 1) {dr = mij;continue;}
            printf("%lld\n", mij);
            break;
        }
        if(rez > p) dr = mij;
        if(rez < p) st = mij;
    }
    fclose(fin);
    fclose(fout);
    return 0;
}