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;
}

End