题意:让求从1开始第k个与m互素的数。
求最大公约数的第一步是用大数对小数取余。gcd(a,b)==gcd(a%b,b),进一步推出gcd(a,b)==gcd(a+b, b)。也就是说,当求出了1~m间与m互质的数之后,把这些数加上m就可以得到m~2m间的与m互质的数。而且m~2m间不会有某个与m互质的数被漏掉。因为如果m<=a<=2m,且gcd(a, m)==1,那么gcd(a - m, m)必然等于1。也就是必然有个在1~m间的数a-m,可以通过加m的方式得到a。所以与m互质的数是有周期性的。我们只需要求出第一个周期即可。
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; long long phi(long long n) { long long rea=n; for(int i=2; i*i<=n; i++) if(n%i==0) { rea=rea-rea/i; do n/=i; while(n%i==0); } if(n>1) rea=rea-rea/n; return rea; } long long gcd(long long a,long long b) { if(!b) return a; return gcd(b,a%b); } int main() { long long m,k,ans; while(~scanf("%I64d%I64d",&m,&k)) { if(m==1) { printf("%I64d\n",k); continue; } int b=phi(m),now=k/b; if(k%b==0)now--; for(long long i=now*m,num=0; i<(now+1)*m; i++) { if(gcd(i,m)==1) num++; if(num+now*b==k) { ans=i; break; } } printf("%I64d\n",ans); } return 0; }