HDU 4497 GCD and LCM(数论+组合数学)
题目大意
给出g,l,求有多少对a,b,c满足gcd(a,b,c)=g,lcm(a,b,c)=l,不同的数之间顺序不同也算不同的对。
解题思路
首先肯定只有\(g|l\)的情况下才有解。从lcm下手,因为三个数的gcd是一样的,所以lcm先除去gcd,然后对l/g分解质因数。
设其中一个质因数为p,指数为k,显然,三个数中必定有一个是\(p^k\),一个是\(p^0\),不然就和gcd与lcm的定义违背了,而第三个数可以是0~k,一共有k+1中选法,然后因为有次序关系,不同的次序结果也不同。
如果第三个数与前两个数都不同,那么一共有6种选法,如果有一个相同,那么有3种选法,结果就是\(6\times (k-1)+3\times 2 = 6\times k\)种选法。由乘法原理可得,最后的结果就是l/g的每个质因子的指数的6倍相乘。
代码
const int maxn = 1e5+10;
const int maxm = 2e2+10;
int p[maxn], u[maxn];
int main() {
for (int i = 2; i<maxn; ++i) {
if (!u[i]) u[i] = p[++p[0]] = i;
for (int j = 1; i*p[j]<maxn; ++j) {
u[i*p[j]] = p[j];
if (i%p[j]==0) break;
}
}
int t; cin >> t;
while(t--) {
ll g, l; cin >> g >> l;
if (l%g) cout << 0 << endl;
else {
ll ans = 1; l /= g;
for (int i = 1; (ll)p[i]*p[i]<=l; ++i)
if (l%p[i]==0) {
int cnt = 0;
while(l%p[i]==0) l /= p[i], ++cnt;
ans *= 6LL*cnt;
}
if (l>1) ans *= 6LL;
cout << ans << endl;
}
}
return 0;
}