Cod sursa(job #214992)

Utilizator ada_sAda-Mihaela Solcan ada_s Data 17 octombrie 2008 11:57:48
Problema Frac Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.59 kb
#include <stdio.h>

//const long long ls=(long long)2305843009213693952;
const long long ls=40;
long long n, p;
long fact[100];
int nrFactori;

long long factPrimi(long long n);
long long f(long long x);
void submultimi(int a, long long sol);
void calcul(bool st[100], long long sol);
long long cautaBin(long long li, long long ls);

int main()
{
	long long rez;
	freopen("frac.in", "r", stdin);
	freopen("frac.out", "w", stdout);
	scanf("%lld%lld", &n, &p);
	nrFactori=factPrimi(n);
	rez=cautaBin(1, ls);
	printf("%lld", rez);
	return 0;
}//main

long long factPrimi(long long n)
{
	long long divizor=3;
	int poz=0;
	if ((n%2)==0)
	{
		fact[poz++]=2;
		while ((n%2)==0)
			n/=2;		
	}//if
	while (n>1)
	{
		if ((n%divizor)==0)
		{
			fact[poz++]=divizor;
			while ((n%divizor)==0)
				n/=divizor;
		}//if
		divizor+=2;
	}//while
	return poz;
}//factPrimi

long long f(long long x)//nr de nr prime cu n <= x
{
	long long sol=x;
	int i;
	for (i=0; i<nrFactori; i++)
		sol-=x/fact[i];
	submultimi(nrFactori, sol);
	return sol;
}//f

void submultimi(int a, long long sol)
{
	bool st[100];
	int k=1;
	st[k]=0;
	while (k>0)
	{
		if (st[k]==0)
		{
			st[k]++;
			if (k==a-1)
				calcul(st, sol);
			else
				st[k++]=0;
		}//if
		else
			st[--k]=0;
	}//while
}//submultimi

void calcul(bool st[100], long long sol)
{
	long long i, t=1;
	for (i=1; i<=n; i++)
		if (st[i])
			t*=fact[i-1];
	sol+=t;
}//calcul

long long cautaBin(long long li, long long ls)
{
	long long lm;
	while (li<ls)
	{
		lm=(li+ls)/2;
		if (p<=f(lm))
			ls=lm;
		else
			li=lm+1;
	}//while
	lm=(li+ls)/2;
	if (f(lm)<p)
		lm++;
	return lm;
}//cautaBin