UVA 10892 LCM Cardinality(数论 质因数分解)

简介:

LCM Cardinality
Input: 
Standard Input

Output: Standard Output

Time Limit: 2 Seconds

 

A pair of numbers has a unique LCM but a single number can be the LCM of more than one possible pairs. For example 12 is the LCM of (1, 12)(2, 12)(3,4) etc. For a given positive integer N, the number of different integer pairs with LCM is equal to N can be called the LCMcardinality of that number N. In this problem your job is to find out the LCM cardinality of a number.

 

Input

The input file contains at most 101 lines of inputs. Each line contains an integer N (0<N<=2*109). Input is terminated by a line containing a single zero. This line should not be processed.

 

Output

For each line of input except the last one produce one line of output. This line contains two integers N and C. Here N is the input number and Cis its cardinality. These two numbers are separated by a single space.

 

Sample Input                             Output for Sample Input

2                                                          
12
24
101101291
0

2 2

12 8

24 11

10110129


题意:给出a和b的最小公倍数N。找出符合条件的a、b有多少对。

分析:1. 设n = LCM(a,b) = (p1^r1) * (p2^r2) * (p3^r3) … (pm^rm)
   又设a=(p1^a1) * (p2^a2) * (p3^a3) … (pm^am),
   b=(p1^b1) * (p2^b2) * (p3^b3)… (pm^bm)
   由LCM的定义有ri = max{ai, bi}
   所以对于每一个ri,ai和bi中至少有一个要取ri
2. 对于ai取ri的情况,bi能够取[0,ri-1]的随意整数,这有ri种情况;
   bi取ri的情况相同是ri种 。
   最后加上ai和bi都取ri的情况,共同拥有(2*ri+1)种情况
3. 由于这么考虑把(a,b)和(b,a)算反复了,但(n,n)的情况仅仅算了一遍。所以最后要ans= (ans+1)/2=ans/2+1(由于ans是奇数)
4. 优化:仅仅考虑√n范围内的质数,但这样会存在漏掉一个大质数的情况(比方n=2*101) 。这个大质数的幂次仅仅能为1(即少算了一个*(2*1+1)),所以在这样的情况发生时要补上ans*=3,写成 位运算就是ans+=ans<<1。

#include <cstdio>
#include <cmath>

int n;

void get_ans() {
    int tmp = n;
    int m = (int)sqrt(n + 0.5);
    long long ans = 1;
    for(int i = 2; i <= m; i += 2) {
        if(n % i == 0) {
            int cnt = 0;
            while(n % i == 0) {
                n /= i;
                cnt++;
            }
            ans *= (cnt << 1) + 1;
        }
        if(i == 2) i--;
    }
    if(n > 1) ans += (ans<<1);
    ans = (ans >> 1) + 1;
    printf("%d %lld\n", tmp, ans);
}

int main() {
    while(~scanf("%d", &n) && n) {
        get_ans();
    }
    return 0;
}






本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5112035.html,如需转载请自行联系原作者
相关文章
|
算法
华为机试HJ108:求最小公倍数
华为机试HJ108:求最小公倍数
101 1
POJ 2689 Prime Distance (埃氏筛 区间筛)
POJ 2689 Prime Distance (埃氏筛 区间筛)
110 0
[Codeforces] 1557 C Moamen and XOR(组合数学)
题意: 用 < 2k的数填充到长度为n的数组中,要使得数组中所有数& >= ^,问方案数 显然,当k == 1的时候,答案为1,只有当所有的数全为1的情况才可以满足题意 对于其他的情况{ 用小于2k的数进行填充,那么说明填充的数字的二进制位数最多可以有k kk位, 从数的个数的角度来说,奇数个1^ 之后的结果是1,偶数个1^ 之后的结果是0,而对于0来讲,不管多少个0,^起来结果都是0 只要有一个0,那么说这一位上&之后就是0,而为了让^为0,那么只能够选择偶数个1 如果某一位上&为1,那么^为1的情况需要讨论n的奇偶性
119 0
HDOJ(HDU) 2504 又见GCD(利用最大公约数反推)
HDOJ(HDU) 2504 又见GCD(利用最大公约数反推)
104 0