GCD and LCM
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 78 Accepted Submission(s): 43
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
题意:
求同时满足gcd(x,y,z)==g&&lcm(x,y,z)==L的(x,y,z)组合数.
题解:
1.很直观的:若l%g!=0||g>l时,答案为0;
2.若果满足l%g==0,用唯一分解定理把个g,l分解,用map保存g,l相同因子个数的差
3.对于x,y,z,其对应的质因子pi应该属于[0,s],s为map[pi],pi的个数,而且x,y,z中必须有一个为0,一个为map[pi],这是为了保证lcm=L,gcd=g;
每个pi对应的种数累乘就是答案了。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<string> #include<algorithm> #include<cstdlib> #include<set> #include<queue> #include<stack> #include<vector> #include<map> #define N 100010 #define Mod 10000007 #define lson l,mid,idx<<1 #define rson mid+1,r,idx<<1|1 #define lc idx<<1 #define rc idx<<1|1 const double EPS = 1e-11; const double PI = acos(-1.0); const double E=2.718281828; typedef long long ll; const int INF=1000010; using namespace std; map<int,int>mp; void Fenjie(int n,int d) { for(int i=2; i*i<=n; i++) { if(n%i==0) { while(n%i==0) { mp[i]+=d; n/=i; } } if(n==1) break; } if(n>1) mp[n]+=d; } int main() { //freopen("in.txt","r",stdin); int n; while(cin>>n) { while(n--) { mp.clear(); int g,l; cin>>g>>l; if(g>l||l%g) { printf("0\n"); continue; } Fenjie(l,1); Fenjie(g,-1); ll ans=1; map<int,int>::iterator it; for(it=mp.begin();it!=mp.end();it++) { if(it->second) { int x=it->second; //ans*=((x+1)*(x+1)*(x+1)-2*x*x*x+(x-1)*(x-1)*(x-1));//容斥原理 ans*=6*x;//组合原理,c(3,1)*c(2,1)*(x-1+1) } } cout<<ans<<endl; } } return 0; }
My code: