题目大意
给定两个数m,k,要求你求出第k个和m互质的数
题解
我们需要知道一个等式,gcd(a,b)=gcd(a+t*b,b)
证明如下:gcd(a+t*b,b)=gcd(b,(a+t*b)%b)=gcd(b,a%b)=gcd(a,b)
所以区间[1,m-1]与m互质的个数等于区间[1+t*m,(t+1)*m-1]与m互质的个数,即都等于phi(m),那么答案就等于第k%phi(m)个与m互素的值p+m*(k/phi(m))
代码:
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> using namespace std; typedef long long LL; #define MAXN 1000000 int check[MAXN+5]; int euler_phi(int n) { int m=(int)sqrt(n+0.5); int ans=n,k=n; memset(check,false,sizeof(check)); for(int i=2; i<=m; i++) if(n%i==0) { ans=ans/i*(i-1); for(int j=1; i*j<=k; j++) check[i*j]=true; while(n%i==0)n/=i; } if(n>1) { ans=ans/n*(n-1); for(int j=1; n*j<=k; j++) check[n*j]=true; } return ans; } int main(void) { int m,k,ans,cnt,t,i; while(cin>>m>>k) { ans=euler_phi(m); cnt=0; if(k%ans==0) t=k/ans-1; else t=k/ans; k=k-ans*t; for(i=1; i<=m; i++) { if(!check[i]) cnt++; if(cnt==k) break; } cout<<i+m*t<<endl; } return 0; }