• hdu4497-GCD and LCM-(欧拉筛+唯一分解定理+组合数)


    GCD and LCM

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


    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
     
    翻译:给出g和l,求满足gcd(x,y,z)=g,lcm(x,y,z)=l的(x,y,z)组合的数量,(1, 2, 3)和(1, 3, 2)算作不同组合
    分析:
    g是因数,l是倍数,显然可以得到x%g=y%g=z%g=0=l%x=l%y=l%z;
    进一步推出l%g=0;若不符合,无解。
     
    根据唯一分解定理
    将x,y,z分解
    x=p1a1*p2a2……psas
    y=p1b1*p2b2……psbs
    z=p1c1*p2c2……pscs
    g是三个数的最大公约数,则g满足g=p1min(a1,b1,c1)……psmin(as,bs,cs)=p1e1……pses 
    l是三个数的最小公倍数,则l满足l=p1max(a1,b1,c1)……psmax(as,bs,cs)=p1h1……pshs
    ei=min(ai,bi,ci) hi=max(ai,bi,bi)
    x,y,z三个数分解后,对于每一个质因子,必然有一个指数是ei,一个指数是hi,先将这两个数固定下来
    另一个数可以取ei到hi之间的数,包括ei和hi,设为ti
    (1)当ti=ei或者ti=hi时,(ei,ei,hi)只有三种组合方式,(ei,hi,hi)也只有三种组合方式
    (2)当ti≠ei并且ti≠hi时,(ei,ti,hi)有6种组合方式
    (3)当ei=ti=hi时,只有1种组合方式
    当ei≠hi时,则每个质因子全部的组合方式有6*(hi-ei)种,组合数用乘法计算结果,当hi=ei,不累乘0
    #include<stdio.h>
    #include<math.h>
    #include<string.h>
    #include<algorithm>
    #include<string>
    #include<vector>
    #include<iostream>
    #include<cstring>
    #define inf 0x3f3f3f3f
    using namespace std;
    #define ll long long
    const int maxx=1e6+5;
    int prime[maxx];
    int vis[maxx];
    ll g,l;
    int cnt;
    void init()
    {
        memset(vis,true,sizeof(vis));
        vis[0]=vis[1]=false;
        cnt=0;
        for(int i=2;i<=maxx;i++)
        {
            if(vis[i])
                prime[cnt++]=i;
            for(int j=0;j<cnt && prime[j]*i<=maxx;j++)
            {
                vis[ i*prime[j] ]=false;
                if(i%prime[j]==0) break;
            }
        }
    }
    
    int main()///hdu4497
    {
        init();
        int t;
        scanf("%d",&t);
        while(t--)
        {
            ll ans=1;
            scanf("%lld%lld",&g,&l);
            if(l%g)
                printf("0
    ");
            else
            {
                for(int i=0;i<cnt;i++)
                {
                    int e=0,h=0;
                    while(g%prime[i]==0)
                    {
                        e++;
                        g=g/prime[i];
                    }
                    while(l%prime[i]==0)
                    {
                        h++;
                        l=l/prime[i];
                    }
                    if(h-e)
                    {
                        ans=ans*(h-e)*6;
                    }
                }
                if(g==l)///32位范围内大素数因子只能有一个,l能被g整除证明这个大素数相同,不累乘
                    ;
                else if(l>1)///如果g=1,l=大素数,再乘一次6
                    ans=ans*6;
                printf("%lld
    ",ans);
            }
        }
        return 0;
    }
     
  • 相关阅读:
    proc文件系统
    sysfs文件系统
    linux 下 进程和线程的区别
    Linux内核中常见内存分配函数
    内核空间与用户空间的通信方式
    DoDataExchange函数,UpdateData(TRUE)和UpdateData(FALSE)的区别
    C# 获取文件路径
    C# WinForm 中 MessageBox的使用详解
    C#对于文件操作
    线程间操作无效: 从不是创建控件的线程访问它。
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/10357950.html
Copyright © 2020-2023  润新知