Cod sursa(job #1344065)

Utilizator fluture.godlikeGafton Mihnea Alexandru fluture.godlike Data 16 februarie 2015 12:08:04
Problema Frac Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.45 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;
}