zoukankan      html  css  js  c++  java
  • HDU44979 GCD and LCM (素因子分解+计数)

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

    题意:

    求有多少种(x,y,z)使得最小公倍数为l,最大公约数为g

    分析:

    我们将l,g进行素因子分解;

    非常明显当g有l没有的素因子 和g的某一个因子的次数大于l的这个因子的次数的时候答案为0;

    然后是有答案的情况下,我们设g中某一个因子数的次数为num1,l中这个因子的次数为num2;

    那么在决定x,y,z在这个因子上的次数时我们要这样考虑,至少有一个为num1,至少有一个为

    num2,然后依据容斥原理能够得出这样的情况的方案数

    代码许下:

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <map>
    using namespace std;
    
    int G[2][50],L[2][50];
    
    int gcd(int a,int b)
    {
        if(b) return gcd(b,a%b);
        return a;
    }
    int main()
    {
        int t,g,l;
        scanf("%d",&t);
        while(t--){
            scanf("%d%d",&g,&l);
            int cnt1=0,cnt2=0;
            memset(G,0,sizeof(G));
            memset(L,0,sizeof(L));
            map<int ,int >mp1;
            map<int ,int >mp2;
            for(int i=2;i<=g;i++){
                if(g%i==0){
                    G[0][cnt1]=i;
                    while(g%i==0){
                        G[1][cnt1]++;
                        g/=i;
                    }
                    cnt1++;
                }
            }
            if(g>1){G[0][cnt1]=g;G[1][cnt1++]=1;}
            for(int i=2;i<=l;i++){
                if(l%i==0){
                    L[0][cnt2]=i;
                    while(l%i==0){
                        L[1][cnt2]++;
                        l/=i;
                    }
                    cnt2++;
                }
            }
            if(l>1) {L[0][cnt2]=l;L[1][cnt2++]++;}
            bool flag=0;
            for(int i=0;i<cnt1;i++)
                mp1[G[0][i]]=G[1][i];
            for(int i=0;i<cnt2;i++)
                mp2[L[0][i]]=L[1][i];
            for(int i=0;i<cnt1;i++){
                if(mp1[G[0][i]]>mp2[G[0][i]])
                    flag=1;
            }
            if(flag){ puts("0"); continue;}
            long long ans=1;
            //cout<<cnt1<<" "<<cnt2<<endl;
            /*****
            cout<<"*******"<<endl;
            for(int i=0;i<cnt1;i++)
                cout<<G[0][i]<<" "<<G[1][i]<<endl;
            cout<<"*******"<<endl;
            for(int i=0;i<cnt2;i++)
                cout<<L[0][i]<<" "<<L[1][i]<<endl;
            cout<<"*******"<<endl;
            ******/
            for(int i=0;i<cnt2;i++){
                int num1=mp1[L[0][i]];
                int num2=mp2[L[0][i]];
                if(num1==num2) continue;
                long long tmp = (num2-num1+1)*(num2-num1+1)*(num2-num1+1);
                tmp-=2*(num2-num1)*(num2-num1)*(num2-num1);
                tmp+=(num2-num1-1)*(num2-num1-1)*(num2-num1-1);
                ans*=tmp;
                cout<<"tmp "<<tmp<<endl;
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    


  • 相关阅读:
    强化学习的基本迭代方法
    基于文本描述的事务聚类
    学习强化学习之前需要掌握的3种技能
    其它 华硕 ASAU S4100U 系统安装 win10安装 重装系统 Invalid Partition Table 解决
    数据分析 一些基本的知识
    Python 取样式的内容 合并多个文件的样式 自定义样式
    电商 Python 生成补单公司需要的评论格式3
    SpringBlade 本地图片上传 生成缩略图
    SQL Server 字符串截取
    SpringBlade 本地图片上传
  • 原文地址:https://www.cnblogs.com/mthoutai/p/6994037.html
Copyright © 2011-2022 走看看