POJ-2773 Happy 2006
题意:给出正数m(1 <= m <= 1000000),求第K (1 <= K <= 100000000)个与m互质的数。
思路:与m互质的数每m的欧拉函数个一循环.如6:1 5,7 11,13 17.....所以求出所有小于m的与m互质的数,然后用k mod m的欧拉函数再乘以相应的倍数。
题目链接:http://poj.org/problem?id=2773
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cmath> 3 #include <cstdlib> 4 #include <cstring> 5 #include <string> 6 #include <algorithm> 7 #include <iostream> 8 using namespace std; 9 const int N=1000010; 10 11 bool isprime[N],flag[N]; 12 int prime[N]; 13 int n,k,cnt; 14 15 void getprime(){ 16 cnt=0; 17 for(int i=2;i<N;i++) 18 if(!isprime[i]){ 19 prime[++cnt]=i; 20 for(int j=2;i*j<N;j++) 21 isprime[i*j]=true; 22 } 23 } 24 25 int phi(int n){ 26 int ans=n; 27 for(int i=2;i*i<=n;i++){ 28 if(n%i==0){ 29 ans=ans-ans/i; 30 while(n%i==0) n/=i; 31 } 32 } 33 if(n>1) ans=ans-ans/n; 34 return ans; 35 } 36 37 int main(){ 38 39 // freopen("data.in","r",stdin); 40 // freopen("data.out","w",stdout); 41 42 getprime(); 43 while(scanf("%d%d",&n,&k)!=EOF){ 44 memset(flag,false,sizeof(flag)); 45 int e=phi(n); 46 int p=k/e; 47 k=k%e; 48 if(k==0) {k=e;p--;} 49 for(int i=1;i<=cnt;i++){ 50 if(n%prime[i]==0){ 51 int m=prime[i]; 52 while(m<=n){ 53 flag[m]=true; 54 m+=prime[i]; 55 } 56 } 57 } 58 int ct=0; 59 for(int i=1;i<=n;i++){ 60 if(!flag[i]) ++ct; 61 if(ct==k){ 62 printf("%d\n",p*n+i); 63 break; 64 } 65 } 66 } 67 return 0; 68 }