Cod sursa(job #2132496)

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

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

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<=62;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";
}