题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2588
题目大意:题目要求小于等于n且与n的最大公约数大于等于m的所有数的个数
方法:使用欧拉函数
那么应该怎么去写呢?首先欧拉函数只能求出小于n且与n互质的所有数的个数,但是里面有我们所需要的数字,所以我们可以对欧拉函数进行修改一下,加一些限制条件,使得能够筛选出我们需要的数字
代码:
1 #include<cstdio> 2 #include <cmath> 3 #include <iostream> 4 5 using namespace std; 6 int Euler(int n) 7 { 8 if(n==1) 9 return 1; 10 int i=2,m=n,root=(int)sqrt(float(n)); 11 while(i<=root) 12 { 13 if(m%i==0) 14 { 15 n-=n/i; 16 while(m%i==0) 17 m/=i; 18 root=(int)sqrt(float(m)); 19 } 20 i++; 21 } 22 if(m!=1) 23 { 24 n-=n/m; 25 } 26 return n; 27 } 28 int solve(int n,int m) 29 { 30 int nn = sqrt(float(n)); 31 int ans=0; 32 for(int i=1;i<=nn;i++) 33 { 34 if(n%i) continue; 35 if(i>=m&&i!=nn) 36 ans += Euler(n/i); 37 if(n/i>=m) 38 ans += Euler(i); 39 } 40 return ans; 41 } 42 int main() 43 { 44 int n,t,m; 45 scanf("%d",&t); 46 while(t--) 47 { 48 scanf("%d%d",&n,&m); 49 printf("%d\n",solve(n,m)); 50 } 51 return 0; 52 }