洛谷P1072 Hankson的趣味题题解--zhengjun

题面传送门

吐槽一句,这么的题目能搞成蓝色???

好了,进入正题:

思路

首先,列出式子:
{ gcd ⁡ ( x , a 0 ) = a 1 l c m ( x , b 0 ) = b 1 \left\{ \begin{aligned} \gcd(x,a_0)=a_1\\ lcm(x,b_0)=b_1 \end{aligned} \right. {gcd(x,a0)=a1lcm(x,b0)=b1

那么,先来看第一个式子:

gcd ⁡ ( x , a 0 ) = a 1 \gcd(x,a_0)=a_1 gcd(x,a0)=a1,设 k 0 = x ÷ a 1 , k 1 = a 0 ÷ a 1 k_0=x\div a_1,k_1=a_0\div a_1 k0=x÷a1,k1=a0÷a1

可以很快得出, gcd ⁡ ( k 0 , k 1 ) = 1 \gcd(k_0,k_1)=1 gcd(k0,k1)=1

证明:

如果 gcd ⁡ ( k 0 , k 1 ) = t , t > 1 \gcd(k_0,k_1)=t,t>1 gcd(k0,k1)=t,t>1,设 k 0 = t × w 0 , k 1 = t × w 1 k_0=t\times w_0,k_1=t\times w_1 k0=t×w0,k1=t×w1

所以 { x = t × w 0 × a 1 a 0 = t × w 1 × a 1 \left\{ \begin{aligned} x=t\times w_0\times a_1\\ a_0=t\times w_1\times a_1 \end{aligned} \right. {x=t×w0×a1a0=t×w1×a1
那么 gcd ⁡ ( x , a 0 ) = a 1 × t \gcd(x,a_0)=a_1\times t gcd(x,a0)=a1×t了,所以 t t t定为 1 1 1

然后,再看第二个式子:

l c m ( x , b 0 ) = b 1 lcm(x,b_0)=b_1 lcm(x,b0)=b1,设 k 0 = b 1 ÷ x , k 2 = b 1 ÷ b 0 k_0=b_1\div x,k_2=b_1\div b_0 k0=b1÷x,k2=b1÷b0,同样可以得出 gcd ⁡ ( k 0 , k 1 ) = 1 \gcd(k_0,k_1)=1 gcd(k0,k1)=1

证明:

gcd ⁡ ( k 0 , k 1 ) = t , t > 1 \gcd(k_0,k_1)=t,t>1 gcd(k0,k1)=t,t>1,设 k 0 = t × w 0 , k 1 = t × w 1 k_0=t\times w_0,k_1=t\times w_1 k0=t×w0,k1=t×w1

{ x = b 1 t × w 0 b 0 = b 1 t × w 1 \left\{ \begin{aligned} x=\dfrac{b_1}{t\times w_0}\\ b_0=\dfrac{b_1}{t\times w_1} \end{aligned} \right. x=t×w0b1b0=t×w1b1
那么, gcd ⁡ ( x , b 0 ) = t × w 0 × w 1 \gcd(x,b_0)=t\times w_0\times w_1 gcd(x,b0)=t×w0×w1,所以, t t t定为 1 1 1

所以,为了满足那个式子,就要 { gcd ⁡ ( x ÷ a 1 , a 0 ÷ a 1 ) = 1 gcd ⁡ ( b 1 ÷ x , b 1 ÷ b 0 ) = 1 \left\{ \begin{aligned} \gcd(x\div a_1,a_0\div a_1)=1\\ \gcd(b_1\div x,b1\div b_0)=1 \end{aligned} \right. {gcd(x÷a1,a0÷a1)=1gcd(b1÷x,b1÷b0)=1
所以, x x x就是 b 1 b_1 b1的因数,只要从 1 1 1 b 1 \sqrt{b_1} b1 ,枚举,然后看看符不符合,这里还有一个潜在的条件,题目中给了我们:输入数据保证 a 0 a_0 a0 能被 a 1 a_1 a1 整除, b 1 b_1 b1 能被 b 0 b_0 b0 整除,所以后面的 a 0 ÷ a 1 a_0\div a_1 a0÷a1 b 1 ÷ b 0 b_1\div b_0 b1÷b0一定是整数,不用管,就要看看 x ÷ a 1 x\div a_1 x÷a1 b 1 ÷ x b_1\div x b1÷x是否为整数就可以了。

代码

#include<bits/stdc++.h>
using namespace std;
int n;
int a0,a1,b0,b1;
int gcd(int x,int y){
	return y==0?x:gcd(y,x%y);
}
int main(){
	scanf("%d",&n);
	while(n--){
		scanf("%d%d%d%d",&a0,&a1,&b0,&b1);
		int ans=0;
		for(int i=1;i*i<=b1;i++){
			if(b1%i==0){
				if(i%a1==0&&gcd(i/a1,a0/a1)==1&&gcd(b1/i,b1/b0)==1)ans++;
				if(i!=b1/i&&b1/i%a1==0&&gcd(b1/i/a1,a0/a1)==1&&gcd(b1/(b1/i),b1/b0)==1)ans++;
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}

谢谢–zhengjun

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

A_zjzj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值