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 }
本文为博主原创文章,未经博主允许不得转载。