Cod sursa(job #1004065)

Utilizator superman_01Avramescu Cristian superman_01 Data 1 octombrie 2013 23:32:43
Problema Frac Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.8 kb
#include <fstream>
#include <algorithm>
#include <vector>
#include <cmath>

#define MAX_SIZE 100005
#define get_max(a,b) ((a)>(b)?(a):(b))

using namespace std;

ifstream in ( "frac.in" );
ofstream out ( "frac.out" ) ;

long long N , P , Answer , Solution , A;
bool ciur[MAX_SIZE];
vector < int > divs , divs_nr;
int v[MAX_SIZE];

void Eratosthene ( void )
{
	int i , j ;
	for ( i = 2 ; i <= MAX_SIZE ; ++i )
		if ( ciur[i] == false )
		{
			divs.push_back( i ) ;
			for ( j = i+i ; j <= MAX_SIZE ; ++j )
				ciur[j] = true ;
		}
}

void MakePrimeNumbers ( void )
{
	long long l = sqrtl(N) , j;
	divs_nr.push_back(0);
	for ( j = 0 ; j < divs.size() && divs[j] <= l ; ++j )
	      if ( N  % divs[j] == 0 ) 
	{
		divs_nr.push_back(divs[j]);
		while ( N% divs[j] == 0 )
			N /= divs[j];		
	}
		  if ( N > 1 )
			  divs_nr.push_back(N);
	divs.clear();
}
long long p[MAX_SIZE];

void DoPinex ( int k  )
{
    int i  ;

    for ( i = v[k-1] +1 ; i <= divs_nr.size() ; ++i )
    { 
        v[k] = i ;
        p[k] = p[k-1] * divs_nr[v[k]];
		bool ok = true ;
		if ( p[k] == 0 )
			continue;
        if ( k % 2 )
            Answer += A/p[k];
        else
            Answer -= A/p[k];
        if ( k < divs_nr.size() )
            DoPinex( k+ 1 );
         
    }
     
}
 
void BinarySearch ( void )
{
	long long left = 1 , right = ( 1LL <<62 );
	while ( left <= right )
	{
		p[0] = 1 ;
		long long middle = ( left + right ) / 2 ;
		A = middle ;
		 DoPinex( 1 ) ;
		if (  middle - Answer >= P )
			{ Solution = middle , right  = middle - 1 ; } 
			else
				left = middle +1 ;
		Answer = 0 ;
	}
}

int main ( void )
{
	in >> N >> P ;
	Eratosthene () ;
	MakePrimeNumbers();
	BinarySearch();
	out << Solution ;
	in.close();
	out.close();
	return 0 ;
}