LOJ 1341 Aladdin and the Flying Carpet(质因子分解)

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

题意:给两个数a,b,求满足c * d = a且c>=b且d>=b的c, d二元组对数,(c, d)和(d, c)属于同一种情况。

思路:根据唯一分解定理,先将a唯一分解,则a的所有正约数的个数为num = (1 + a1) * (1 + a2) *...* (1 + ai),这里的ai是素因子的指数。现在我们知道了a的因子个数为num,假设因子从小到大排列为

X1,X2,...,Xnum 因为是求二元组,所以num先除以2,然后减去那些比b小的因子即可(比b小的一定和比较大的组合,所以不用考虑很大的情况)。

code:

 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4 
 5 typedef long long LL;
 6 const int MAXN = 1000000;
 7 
 8 int prime[MAXN + 1];
 9 
10 void getPrime()
11 {
12     memset(prime, 0, sizeof(prime));
13     for (int i = 2; i <= MAXN; ++i) {
14         if (!prime[i]) prime[++prime[0]] = i;
15         for (int j = 1; j <= prime[0] && prime[j] <= MAXN / i; ++j) {
16             prime[prime[j] * i] = 1;
17             if (i % prime[j] == 0) break;
18         }
19     }
20 }
21 
22 LL factor[1000][2];
23 int fatCnt;
24 
25 int getFactors(LL x)
26 {
27     fatCnt = 0;
28     LL tmp = x;
29     for (int i = 1; i <= prime[0] && prime[i] * prime[i] <= tmp; ++i) {
30         factor[fatCnt][1] = 0;
31         if (tmp % prime[i] == 0) {
32             factor[fatCnt][0] = prime[i];
33             while (tmp % prime[i] == 0) {
34                 ++factor[fatCnt][1];
35                 tmp /= prime[i];
36             }
37             ++fatCnt;
38         }
39     }
40     if (tmp != 1) {
41         factor[fatCnt][0] = tmp;
42         factor[fatCnt++][1] = 1;
43     }
44     LL ret = 1;
45     for (int i = 0; i < fatCnt; ++i) {
46         ret *= (1L + factor[i][1]);
47     }
48     return ret;
49 }
50 
51 int main()
52 {
53     getPrime();
54     int nCase;
55     scanf("%d", &nCase);
56     for (int cnt = 1; cnt <= nCase; ++cnt) {
57         LL a, b;
58         scanf("%lld %lld", &a, &b);
59         if (b * b > a) {
60             printf("Case %d: 0\n", cnt);
61             continue;
62         }
63         LL num = getFactors(a);
64         num /= 2;
65         for (int i = 1; i < b; ++i) {
66             if (a % i == 0) --num;
67         }
68         printf("Case %d: %lld\n", cnt, num);
69     }
70     return 0;
71 }

 

posted @ 2015-09-02 13:09  jasaiq  阅读(331)  评论(0编辑  收藏  举报