zoukankan      html  css  js  c++  java
  • 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
    ", tmp, ans);
    }
    
    int main() {
        while(~scanf("%d", &n) && n) {
            get_ans();
        }
        return 0;
    }


  • 相关阅读:
    android 75 新闻列表页面
    android 74 下载文本
    android 73 下载图片
    android 72 确定取消对话框,单选对话框,多选对话框
    android 71 ArrayAdapter和SimpleAdapter
    android 70 使用ListView把数据显示至屏幕
    maven如何将本地jar安装到本地仓库
    Centos6.7搭建ISCSI存储服务器
    解决maven打包编译出现File encoding has not been set问题
    MySQL 解决 emoji表情 的方法,使用utf8mb4 字符集(4字节 UTF-8 Unicode 编码)
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5112035.html
Copyright © 2011-2022 走看看