LightOj 1236 Pairs Forming LCM (素数筛选&&唯一分解定理)

题目大意:

  有一个数n,满足lcm(i,j)==n并且i<=j时,(i,j)有多少种情况?

解题思路:

  n可以表示为:n=p1^x1*p2^x1.....pk^xk。

  假设lcm(a,b) == n;

  a = p1^c1 * p2^c2 ..... pk^ck。

  b = p1^e1 * p2^e2 .... pk^ek。

  xi = max(ci, ei)。

  对于有序数对(a,b),有唯一分解定理知,每一个素因数的幂都决定了一个独一无二的数。

  求(a,b)的种数就可以转化为求(ci,ei)的种数:num = (2*x1+1)*(2*x2+1).....(2*xk+1)。

  因为是有序数对,最后在除于二。

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 
 8 #define maxn 10000050
 9 char a[maxn];
10 int b[700000];
11 void prime ();//素数筛选
12 int main ()
13 {
14     int t, l = 1;
15     long long n, sum;
16     prime ();
17     scanf ("%d", &t);
18     while (t --)
19     {
20         scanf ("%lld", &n);
21         int i = 0;
22         sum = 1;
23         while (n > 1 && i < 664580)//由于内存有限,筛选的素数有限,所以i大于所筛选出的素数时也应该退出
24         {
25             if (n % b[i] == 0)
26             {
27                 int j = 0;
28                 while (n % b[i] == 0)
29                 {
30                     n /= b[i];
31                     j ++;
32                 }
33                 sum *= (2 * j + 1);
34             }
35             i++;
36         }
37         if (n != 1)//因为筛选出来的素数有限,n!=1的时候,肯定有一个素数并且这个素数只有一个
38             sum *= 3;
39         printf ("Case %d: %lld\n", l++, (sum+1)/2);
40     }
41     return 0;
42 }
43 
44 void prime ()
45 {
46     long long i, j, k;
47     for (k=0,i=2; i<maxn; i++)
48     {
49         if (!a[i])
50         {
51             b[k ++] = i;
52              for (j=i*i; j<maxn; j+=i)
53                 a[j] = 1;
54         }
55     }
56 }

 

posted @ 2015-04-27 16:40  罗茜  阅读(245)  评论(0编辑  收藏  举报