HDU 4497 GCD and LCM (合数分解)

GCD and LCM

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

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
2013 ACM-ICPC吉林通化全国邀请赛——题目重现  

 

Recommend liuyiding  

 

 

 

对G和L 分别进行合数分解。

 

很显然,如果G中出现了L中没有的素数,或者指数比L大的话,肯定答案就是0了、

 

对于素数p,如果L中的指数为num1,G中的指数为num2.

显然必须是num1 >= num2;

 

3个数p的指数必须在num1~num2之间,而且必须有一个为num1,一个为num2

容斥原理可以求得种数是:

 (num1-num2+1)*(num1-num2+1)*(num1-num2+1) – 

2*(num1-num2)*(num1-num2)*(num1-num2) + 

 (num1-num2-1)*(num1-num2-1)*(num1-num2-1);

 

 

然后乘起来就是答案:

  1 /* ***********************************************
  2 Author        :kuangbin
  3 Created Time  :2013/8/24 12:48:31
  4 File Name     :F:\2013ACM练习\比赛练习\2013通化邀请赛\1005.cpp
  5 ************************************************ */
  6 
  7 #include <stdio.h>
  8 #include <string.h>
  9 #include <iostream>
 10 #include <algorithm>
 11 #include <vector>
 12 #include <queue>
 13 #include <set>
 14 #include <map>
 15 #include <string>
 16 #include <math.h>
 17 #include <stdlib.h>
 18 #include <time.h>
 19 using namespace std;
 20 
 21 const int MAXN = 1000000;
 22 int prime[MAXN+1];
 23 void getPrime()
 24 {
 25     memset(prime,0,sizeof(prime));
 26     for(int i = 2;i <= MAXN;i++)
 27     {
 28         if(!prime[i])prime[++prime[0]] = i;
 29         for(int j = 1;j <= prime[0] && prime[j] <= MAXN/i;j++)
 30         {
 31             prime[prime[j]*i] = 1;
 32             if(i % prime[j] == 0)break;
 33         }
 34     }
 35 }
 36 long long factor[100][2];
 37 int fatCnt;
 38 int getFactors(long long x)
 39 {
 40     fatCnt = 0;
 41     long long tmp = x;
 42     for(int i = 1; prime[i] <= tmp/prime[i];i++)
 43     {
 44         factor[fatCnt][1] = 0;
 45         if(tmp % prime[i] == 0 )
 46         {
 47             factor[fatCnt][0] = prime[i];
 48             while(tmp % prime[i] == 0)
 49             {
 50                 factor[fatCnt][1] ++;
 51                 tmp /= prime[i];
 52             }
 53             fatCnt++;
 54         }
 55     }
 56     if(tmp != 1)
 57     {
 58         factor[fatCnt][0] = tmp;
 59         factor[fatCnt++][1] = 1;
 60     }
 61     return fatCnt;
 62 }
 63 int a[100],b[100];
 64 map<int,int>mp1,mp2;
 65 int main()
 66 {
 67     //freopen("in.txt","r",stdin);
 68     //freopen("out.txt","w",stdout);
 69     getPrime();
 70     //for(int i = 1;i <= 20;i++)
 71         //cout<<prime[i]<<endl;
 72     int n,m;
 73     int T;
 74     scanf("%d",&T);
 75     while(T--)
 76     {
 77         scanf("%d%d",&n,&m);
 78         mp1.clear();
 79         mp2.clear();
 80         getFactors(m);
 81         int cnt1 = fatCnt;
 82         for(int i = 0;i < cnt1;i++)
 83         {
 84             mp1[factor[i][0]] = factor[i][1];
 85             a[i] = factor[i][0];
 86             //printf("%I64d %I64d\n",factor[i][0],factor[i][1]);
 87         }
 88         getFactors(n);
 89         int cnt2 = fatCnt;
 90         bool flag = true;
 91         for(int i = 0;i < cnt2;i++)
 92         {
 93             mp2[factor[i][0]] = factor[i][1];
 94             if(mp1[factor[i][0]] < factor[i][1])
 95                 flag = false;
 96             b[i] = factor[i][0];
 97             //printf("%I64d %I64d\n",factor[i][0],factor[i][1]);
 98         }
 99         if(!flag)
100         {
101             printf("0\n");
102             continue;
103         }
104         int ans = 1;
105         for(int i = 0;i < cnt1;i++)
106         {
107             int num1 = mp1[a[i]];
108             int num2 = mp2[a[i]];
109             if(num1 == num2)
110                 ans *= 1;
111             else
112             {
113                 long long tmp = (num1-num2+1)*(num1-num2+1)*(num1-num2+1);
114                 tmp -= 2*(num1-num2)*(num1-num2)*(num1-num2);
115                 tmp += (num1-num2-1)*(num1-num2-1)*(num1-num2-1);
116                 ans *= tmp;
117             }
118         }
119         printf("%d\n",ans);
120     }
121     return 0;
122 }

 

 

 

 

 

 

 

 

 

    原文作者:算法小白
    原文地址: https://www.cnblogs.com/kuangbin/p/3279626.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞