码迷,mamicode.com
首页 > 其他好文 > 详细

UVA 10892

时间:2014-10-17 15:37:49      阅读:260      评论:0      收藏:0      [点我收藏+]

标签:数学

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;
}


UVA 10892

标签:数学

原文地址:http://blog.csdn.net/lyhvoyage/article/details/40185461

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!