P1072 Hankson 的趣味题
题目大意:
求有多少个 \(x\) 满足:
\[\gcd(x,a_0)=a_1,\text{lcm}(x,b_0)=b_1 \]
solution:
首先我们探究一些性质:设\(x=k_1\times a_1,a_0=k_2\times a_1\) ,且 \(\gcd(k_1,k_2)=1\) 。
证明:
若 \(\gcd(k_1,k_2)\not=1\),设 \(\gcd(k_1,k_2)=d\) ,则有 \(k_1=d\times p_1\,\,,\,\,k_2=d\times p_2\) ,则有 \(x=d\times p_1\times a_1\,\,,\,\,a_0=d\times p_2\times a_1\) ,这时 \(\gcd(x,a_0)=a_1\times d\not=a_1\) 与原式不符。
证毕。
所以我们有 \(\gcd(\frac{x}{a_1},\frac{a_0}{a_1})=1\) ,同理推广第二个柿子:
\[\gcd(x,b_0)=x\times b_0/\text{lcm}(x,b_0)=x\times b_0/b_1 \] \[\therefore \gcd(x/x/b_0\times b_1,b_0/x/b_0\times b_1)=1 \]\(\gcd(\frac{b_1}{b_0},\frac{b_1}{x})=1\) 。
所以我们枚举 \(b_1\) 的因子 \(x\) ,看 \(a_1\) 是否是 \(x\) 的因子,并满足上面两个柿子。
代码
#include<cstdio>
using namespace std;
inline int gcd(int a,int b){
if(!b) return a;
return gcd(b,a%b);
}
int main(){
int n; scanf("%d",&n);
while(n--){
int a0,a1,b0,b1,ans=0;
scanf("%d%d%d%d",&a0,&a1,&b0,&b1);
int a0_a1=a0/a1,b1_b0=b1/b0;
for(int x=1;x<=b1/x;x++){
if(b1%x==0){
if(x%a1==0&&gcd(x/a1,a0_a1)==1&&gcd(b1_b0,b1/x)==1) ans++;
int y=b1/x;
if(x==y) continue;
if(y%a1==0&&gcd(y/a1,a0_a1)==1&&gcd(b1_b0,b1/y)==1) ans++;
}
}
printf("%d\n",ans);
}
return 0;
}