题意
给你
,让你找到第
个与
和
互素的数。
思路:
范围比较大,我们可以先找出
和
的质因子,然后二分答案。每次容斥判定
是第几个与
和
互质的数字。
#include <iostream>
#include <cstring>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <cstdio>
#include <sstream>
#include <algorithm>
using namespace std;
#define read(x) scanf("%d", &x)
#define Read(x, y) scanf("%d%d", &x, &y)
#define gc(x) scanf(" %c", &x);
#define mmt(x, y) memset(x, y, sizeof x)
#define write(x) printf("%d\n", x)
#define INF 0x3f3f3f3f
#define ll long long
#define mod 998244353
const ll N = 1e5 + 5;
ll prime[N];
int idx = 0;
ll ok(ll n)
{
ll s = (1 << idx);
ll ans = 0;
for (ll i = 1; i < s; ++i)
{
int cnt = 0;
ll p = 1;
for (ll j = 0; j < idx; ++j)
{
if ((i >> j) & 1)
{
cnt++;
p *= prime[j + 1];
}
}
if (cnt & 1) ans += n / p;
else ans -= n / p;
}
return n - ans;
}
int main()
{
int t;
read(t);
for(int Case = 1;Case <= t;++Case)
{
idx = 0;
ll m, n, k;
scanf("%lld%lld%lld",&m,&n,&k);
for (ll i = 2; i * i <= m; i++)//分解质因子
{
if (!(m % i))
{
prime[++idx] = i;
while (!(m % i))
m /= i;
}
}
if (m > 1)
prime[++idx] = m;
for (ll i = 2; i * i <= n; ++i)
{
if (!(n % i))
{
prime[++idx] = i;
while (!(n % i))
n /= i;
}
}
if (n > 1)
prime[++idx] = n;
ll l = 1, r = 1e14;
sort(prime + 1, prime + idx + 1);
int p = unique(prime + 1, prime + idx + 1) - prime - 1;
idx = p;
while (l < r)//二分答案
{
ll mid = l + r >> 1;
ll ans = ok(mid);
if (ans >= k)
r = mid;
else
l = mid + 1;
}
printf("Case %d: %lld\n",Case,r);
}
}