Cod sursa(job #1344063)

Utilizator fluture.godlikeGafton Mihnea Alexandru fluture.godlike Data 16 februarie 2015 12:06:57
Problema Frac Scor 100
Compilator cpp Status done
Runda prega_rav_1 Marime 1.81 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;
	//printf("temp2 = %lld\n", temp2);
	size = 0;
	if(temp2%2 == 0)
	{
		//printf("check2\n");
        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)
		{
			//printf("check%d\n", i);
            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);
	//printf("%lld %lld\n", n, p);
	fp();
	//for(int i = 0; i< size; i++) printf("%d ", div[i]);printf("\n");
	for( ; ; )
	{
		//printf("check\n");
		mij = (st+dr)/2;
		rez = mij;
		//printf("st =%lld dr = %lld mij = %lld\n", st, dr, mij);
		//printf("check\n");
		//getch();
		for(int i = 1; i<= size; i++)
		{
			temp = i;
            if(i%2) rez -= comb(i, 1);
			else rez += comb(i, 1);
		}
		//printf("rez = %d\n", rez);
		//getch();
		if(rez == p)
		{
			if(gcd(mij, n) > 1) {dr = mij;continue;}
            printf("%lld\n", mij);
			//getch();
			break;
		}
		if(rez > p) dr = mij;
		if(rez < p) st = mij;
	}
	fclose(fin);
	fclose(fout);
	return 0;
}