Cod sursa(job #3305047)

Utilizator Ilie_MityIlie Dumitru Ilie_Mity Data 29 iulie 2025 16:45:09
Problema Frac Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.13 kb
// Ilie "The-Winner" Dumitru
// Dumnezeu sa o ierte
#include<bits/stdc++.h>
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define err(...) fprintf(stderr, __VA_ARGS__)
using ll=long long;
constexpr int NMAX=100005;
constexpr ll MOD=1000000007;

struct el
{
	ll D;
	int p;
};

ll N, P, phi;
std::vector<ll> prime;
std::vector<el> divs;

void back(int k, ll D, int p)
{
	if(k==sz(prime))
		divs.push_back({D, p});
	else
	{
		back(k+1, D, p);
		back(k+1, D*prime[k], !p);
	}
}

void fact()
{
	ll i, N=::N;

	phi=N;

	for(i=2;i*i<=N;++i)
		if(N%i==0)
		{
			do N/=i; while(N%i==0);
			prime.push_back(i);
		}
	if(N>1)
		prime.push_back(N);

	for(ll x : prime)
		phi-=phi/x;

	back(0, 1, 0);
}

ll count(ll x)
{
	ll ans=0;

	for(el e : divs)
		if(e.p)
			ans-=x/e.D;
		else
			ans+=x/e.D;

	return ans;
}

int main()
{
	FILE* f=fopen("frac.in", "r"), *g=fopen("frac.out", "w");
	ll ans, l, r, mid;

	fscanf(f, "%lld%lld", &N, &P);
	fact();

	ans=N*((P-1)/phi);
	P=(P-1)%phi+1;

	for(l=0, r=N-1;r-l>1;)
	{
		mid=l+((r-l)>>1);
		if(count(mid)<P)
			l=mid;
		else
			r=mid;
	}

	fprintf(g, "%lld\n", ans+r);

	fclose(f);
	fclose(g);
	return 0;
}