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 }