• hdu_4497GCD and LCM(合数分解)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4497

    GCD and LCM

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
    Total Submission(s): 2151    Accepted Submission(s): 955


    Problem Description
    Given two positive integers G and L, could you tell me how many solutions of (x, y, z) there are, satisfying that gcd(x, y, z) = G and lcm(x, y, z) = L? 
    Note, gcd(x, y, z) means the greatest common divisor of x, y and z, while lcm(x, y, z) means the least common multiple of x, y and z. 
    Note 2, (1, 2, 3) and (1, 3, 2) are two different solutions.
     


    Input
    First line comes an integer T (T <= 12), telling the number of test cases. 
    The next T lines, each contains two positive 32-bit signed integers, G and L. 
    It’s guaranteed that each answer will fit in a 32-bit signed integer.
     


    Output
    For each test case, print one line with the number of solutions satisfying the conditions above.
     


    Sample Input
    2 6 72 7 33
     


    Sample Output
    72 0
     


    Source
    题意:给出三个数的最大公约数和最小公倍数,让求abc这三个数可能的情况,注意ABC的位置不同算不同的情况
    考虑先分解最小公倍数。合数分解后,再分解最大公约数,可知,如果最大公约数中有最小公倍数中没有的质因数因子的话,那么答案肯定为0
    然后考虑每一个因子pi有设合数分解最小公倍数的个数为bi合数分解最大公约数的个数为bi
    下面有两种考虑方法
      排列组合:易得三个数中的对于pi的情况必须有一个个数是bi,另一个是ai,然后就可以先选出两个位置一个bi一个ai然后最后一个位置上的个数一定介于ai和bi之间即(bi-ai-1)种情况。
    所以最后的公式为ans *=  A(3,2)*(bi-ai-1) = 6*(bi-ai-1) ;
    注意,如果先筛素数的时候筛到1^6 然后如果L除以最后一个素数的时候不等于1,那么说明它(L的最后一个因子)一定是大于10^6的一个素数,因为10^12 = 10^6^2 > x^2>y;如果y存在一个非素数的因子k的话,有k*t = y 且k>x,则t<x则t已经被筛掉了。所以剩下的因子一定是素因子。一开始没有考虑这种特殊情况wa掉了。。。
    注意,还要注意只有当(bi-ai-1) 有意义的时候才可以计算,因为如果bi==ai的时候可以发现正确结果是对于这一位应该是只用一种情况,就是三个数都相等,所以要特判一下。。。。后来又因为这个wa了一次~~~~(>_<)~~~~
      容斥定理:同样是考虑每个因子,有所有的情况是每个位置都可以取(bi-ai+1)种情况即(bi-ai+1)^3,要减去没有bi个因子的情况和没有ai个因子的情况即2*(bi-ai)^3
    然后发现减多了,要加上同时没有因子ai和bi的情况即(bi-ai-1)^3
    这里同样要注意上面的注意。
     1 //合数分解
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 #define ll long long
     7 const int maxn = 1000005;
     8 int prime[maxn];
     9 bool pri[maxn];
    10 int cnt;
    11 void init()
    12 {
    13     cnt = 0;
    14     pri[0] = pri[1] = 1;
    15     //prime[0] = 2;
    16     for(int i = 2; i < maxn; i++){
    17         if(!pri[i]){
    18 
    19             prime[cnt++] = i;
    20             for(int j = i+i; j < maxn; j+=i)
    21             {
    22                 pri[j]=1;
    23             }
    24         }
    25     }
    26     return;
    27 }
    28 ll m1[10005],m2[10005];
    29 ll c1[10005],c2[10005];
    30 int main()
    31 {
    32     init();
    33     int T;
    34     ll G,L;
    35     scanf("%d",&T);
    36     while(T--)
    37     {
    38         memset(m1,0,sizeof(m1));
    39         memset(c1,0,sizeof(c1));
    40         memset(m2,0,sizeof(m2));
    41         memset(c2,0,sizeof(c2));
    42         scanf("%lld%lld",&G,&L);
    43         int tm = 0;
    44         bool in = 0;
    45         bool fl = 1;
    46         //printf("%d
    ",prime[1]);
    47         if(L%G) fl = 0;
    48         for(int i = 0; i< cnt; i++){
    49             while(prime[i]<=L&&L%prime[i]==0){
    50                 L = L/prime[i];
    51                 m2[tm] = prime[i];
    52                 c2[tm]++;
    53                 in = 1;
    54             }
    55             if(in) tm++;
    56             in = 0;
    57         }
    58         if(L!=1){
    59             m2[tm] = L;
    60             c2[tm] = 1;
    61             tm++;
    62         }
    63         for(int i = 0; i < tm; i++){
    64             while(m2[i]<=G&&G%m2[i]==0){
    65                 G = G/m2[i];
    66                 m1[i] = m2[i];
    67                 c1[i]++;
    68             }
    69             in = 0;
    70         }
    71         if(G!=1){
    72            fl = 0;
    73         }
    74         /*puts("haha");
    75         for(int i = 0; i < tm; i++){
    76             printf("m1[%d]=%d; m2[%d]=%d;
    ",i,m1[i],i,m2[i]);
    77             printf("c1[%d]=%d; c2[%d]=%d;
    ",i,c1[i],i,c2[i]);
    78         }
    79         */
    80         if(fl==0) {puts("0"); continue;}
    81         ll ans = 1;
    82         for(int i = 0; i < tm; i++){
    83             //需要特判当c1[i] =c2[i]的情况
    84             ll E;
    85             if(c1[i]==c2[i]) E = 0;
    86             else E = c2[i]-c1[i]-1;
    87             /*
    88                 也可以用排列组合的想法,每次找到两个数包含首尾的两个值,然后中间的一个在从所有可能中选取一个。
    89                 这样最后的公式就是A(3,2)*(c2[i]-c1[i]-1);
    90                 所以
    91                 if(c2[i]>c1[i]) ans = ans*6*(c2[i]-c1[i]-1);
    92                     */
    93             ans = ans*((c2[i]-c1[i]+1)*(c2[i]-c1[i]+1)*(c2[i]-c1[i]+1)-2*(c2[i]-c1[i])*(c2[i]-c1[i])*(c2[i]-c1[i])+E*E*E);
    94         }
    95         printf("%lld
    ",ans);
    96     }
    97     return 0;
    98 }
  • 相关阅读:
    TOJ 3660 家庭关系
    TOJ 2857 Stockbroker Grapevine
    关于字符串不为空 错误:s!=null
    根据判断数组不为空然后取他的值----数组不会为空---只能判断其size是否大于0
    JRebel 7.1.5 插件下载 安装 激活 结合 IntelliJ IDEA--自动编译进行热部署---
    @requestbody---接受前端传json对象并绑定javabean
    json转换时区问题-------前端展示时间少8小时--解决方法
    使用Mybatis-Generator自动生成Dao、Model、Mapping相关文件(转)-----https://www.cnblogs.com/smileberry/p/4145872.html
    数据库设计软件介绍--几种数据库建模工具推荐(包含开源版)
    mysql 查询当天、本周,本月,上一个月的数据---https://www.cnblogs.com/benefitworld/p/5832897.html
  • 原文地址:https://www.cnblogs.com/shanyr/p/5672302.html
Copyright © 2020-2023  润新知