Cod sursa(job #2132467)

Utilizator shantih1Alex S Hill shantih1 Data 15 februarie 2018 19:50:23
Problema Frac Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.09 kb
#include <iostream>
#include <fstream>
#include <cmath>
#define ll long long
using namespace std;
ifstream fin("frac.in");
ofstream fout("frac.out");

int n,k,z[20],i,j,nr,p,nrpr[100],np,vpl,vmn;
ll plu[100000],mns[100000],st,dr,mid,sum;

void calc()
{
	ll p=1;
	for(int i=1;i<=k;i++)	p*=nrpr[z[i]];
	if(k%2==1)
	{	vpl++;	plu[vpl]=p;	}
	else { vmn++;	mns[vmn]=p;	}
}
void back(int niv)
{
	if(niv==k+1)	calc();
	else
		for(int i=z[niv-1]+1;i<=np;i++)
		{
			z[niv]=i;
			back(niv+1);
		}
}

int main() {
	
	fin>>n>>p;
	if(n%2==0)
	{	np++;	nrpr[np]=2;		}
	while(n%2==0)	n/=2;

	for(i=3;i<=sqrt(n);i+=2)
	{
		if(n%i==0)
		{	np++;	nrpr[np]=i;	}
		while(n%i==0)	n/=i;
	}
	if(n>2)
	{	np++;	nrpr[np]=n;	}
	
	for(k=1;k<=np;k++)	back(1);
	
	dr=1;
	for(i=1;i<=61;i++)
		dr*=2;
	st=1;
	while(st<=dr)
	{
		mid=st+(dr-st)/2;
		sum=0;
		for(i=1;i<=vpl;i++)
			sum+=mid/plu[i];
		for(i=1;i<=vmn;i++)
			sum-=mid/mns[i];
		sum=mid-sum;
		
		if(sum<p)	st=mid+1;
		if(sum>=p)	dr=mid-1;
	}

	sum=0;
	for(i=1;i<=vpl;i++)
		sum+=mid/plu[i];
	for(i=1;i<=vmn;i++)
		sum-=mid/mns[i];
	sum=mid-sum;
	if(sum<p)	mid++;
	
	fout<<mid<<"\n";
}