lightoj 1341

lightoj 1341  Aladdin and the Flying Carpet

链接http://lightoj.com/volume_showproblem.php?problem=1341

题意:给定整数 a, b ,求 区间[b, a] 内的 a 的约数对的个数,a 的约数对(比如[2, 3] 与 [3, 2] 是同一对),也就是说前因子要小于后因子。

思路:我的思路比较直接,就是求 a 的约数的个数(用欧拉函数),除以 2 就得到约数对数, 然后暴力求解区间 [1, b] 内的 a 的约数。最后两数相减得到结果。

代码

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <algorithm>
 4 #include <queue>
 5 #include <map>
 6 #include <set>
 7 #include <vector>
 8 #include <cstring>
 9 #include <math.h>
10 using namespace std;
11 
12 typedef long long LL;
13 const int maxv = 1000005;
14 bool nu[maxv];
15 int phi[80000], k;
16 
17 void prime()        //素数表
18 {
19     memset(nu, 0, sizeof(nu));
20     int i, j;
21     k = 1;
22     nu[4] = 1, phi[0] = 2;
23     for(i = 3; i < maxv; i += 2)
24     {
25         if(!nu[i])    phi[k++] = i;
26         for(j = 0; j < k && i * phi[j] < maxv; j++)
27         {
28             nu[i*phi[j]] = 1;
29             if(!(i % phi[j]))    break;
30         }
31     }
32 }
33 
34 LL gain_ans(LL a)        //得到区间[1, a] 的约数对数
35 {
36     int i = 0, j;
37     LL s = 1;
38     if(a == 0)        return 0;
39     while(phi[i] < a && i < k )    //欧拉函数
40     {
41         j = 0;
42         if(a % phi[i] == 0)
43             while(a % phi[i] == 0)
44                 a /= phi[i], j++;
45         s *= (j+1);
46         i++;
47     }
48     if(a != 1)    s *= 2;
49     return s / 2;
50 }
51 
52 int main()
53 {
54     LL  b, a, s, q;
55     int t, cs = 1;
56     prime();
57     freopen("lightoj1341.txt", "r", stdin);
58     cin >> t;
59     while(t--)
60     {
61         scanf("%lld%lld", &a, &b);
62         q = 0;
63         if(b >= sqrt(a))    s = 0;        // b 大小限定 
64         else
65         {
66             q = 0;
67             for(int i = 1; i < b; ++i)    //暴力枚举 [1, b] 的a 的约数
68                 if(a % i == 0)    q++;
69             s = gain_ans(a) - q;
70         }
71         printf("Case %d: %lld\n", cs++, s);
72     }
73     return 0;
74 }

 

posted @ 2013-07-29 11:07  妮king狼  阅读(599)  评论(0编辑  收藏  举报