/* *Time: 0 ms *题目大意: * 输入m, n(n < 1000000000),求1~n之间中gcd(x, n) >=m 的x个数。 *解题思路: * 找出N的所有大于等于M的因子(x1,x2,x3.....xi),然后设k=N/xi; * 下面只需找出小于k且与k互质的数。 * 因为:设y与k互质且小于k,那么gcd(y*xi,k*xi)=xi; * (xi为N的因子,且xi大于等于M)。 */
View Code
1 #include <iostream> 2 #include <algorithm> 3 #include <cmath> 4 using namespace std; 5 6 const int MAX = 1000000; 7 int factor[MAX]; 8 9 int init(int n) 10 { 11 int cnt = 0; 12 int e = (int)sqrt((double)n); 13 int i; 14 for(i = 1; i < e; i++) 15 { 16 if(n % i == 0) 17 { 18 factor[cnt++] = i; 19 factor[cnt++] = n / i; 20 } 21 } 22 if(n % i == 0) 23 factor[cnt++] = i; 24 sort(factor, factor + cnt); 25 return cnt; 26 } 27 28 int euler(int x) 29 { 30 // 就是公式 31 int i, res = x; 32 for (i = 2; i < (int)sqrt(x * 1.0) + 1; i++) 33 if(x % i == 0) 34 { 35 res = res / i * (i - 1); 36 while (x % i == 0) x /= i; // 保证i一定是素数 37 } 38 if (x > 1) 39 res = res / x * (x - 1); 40 return res; 41 } 42 43 int main(void) 44 { 45 int cas; 46 scanf("%d", &cas); 47 while(cas--) 48 { 49 int m, n; 50 scanf("%d %d", &n, &m); 51 int len = init(n); 52 int i; 53 for(i = 0; i < len; i++) 54 { 55 if(factor[i] >= m) 56 break; 57 } 58 int ans = 0; 59 for(; i < len; i++) 60 { 61 int t = n / factor[i]; 62 ans += euler(t); 63 } 64 cout << ans << endl; 65 } 66 return 0; 67 }