/*
*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 }
posted on 2012-07-19 02:03  cchun  阅读(864)  评论(0编辑  收藏  举报