题目
思路
该题求的是某个数是第几个与给出的数互质的数,也就是说,该数前面与给出的数不互质的数确定,看作一个集合,想到容斥原理+最小质因子来求解,即将m分解质因子,二进制枚举组合,某数能整除某个组合的就看作在集合中,剩下的就是互质的,容斥原理求集合大小;某个数的值减去求得的集合就是与m互质的第几个,而找到答案,二分查找就行了
AC代码
#include <iostream>
using namespace std;
int prime[100000]={0};
long long cnt=0,x=0;
long long kind(long long s)
{
long long ans=s;
for(long long i=1;i<=x;i++)
{
long long j=i,p=1,sign=0;
long long res=1;
while(j)
{
if(j&1) res*=prime[sign],p*=-1;
j>>=1;
sign++;
}
ans+=(s/res)*p;
}
return ans;
}
int main()
{
long long n,k;
while(scanf("%lld%lld",&n,&k)!=EOF)
{
long long m=n;
cnt=0;
for(int i=2;i*i<=n;i++)
{
if(m%i==0) prime[cnt++]=i;
while(m%i==0) m/=i;
}
if(m>1) prime[cnt++]=m;
x=(1ll<<cnt)-1;
long long l=1,r=1e17;
while(l<r)
{
long long mid=(l+r)/2;
if(kind(mid)>=k) r=mid;
else l=mid+1;
}
printf("%lld\n",r);
}
return 0;
}