P1072 [NOIP2009 提高组] Hankson 的趣味题
P1072 [NOIP2009 提高组] Hankson 的趣味题
0x01 题意
给出\(a_0,a_1,b_0,b_1\),求\(x\)的个数使得:
-
\(x\)和\(a_0\)的最大公约数是\(a_1\).
-
\(x\)和\(b_0\)的最小公倍数是\(b_1\).
0x02 解
有一个定理是这样说的:
对于两个正整数\(a,b\),设\(gcd(a,b)=k\),则存在\(gcd(a/k,b/k)=1\)
证明:显然
把俩条件变下型就成了
\[\begin{cases}gcd(x/a_1,a_0/a_1)=1\\gcd(b_1/b_0,b_1/x)=1\end{cases}
\]
发现什么?
\(x\)既是\(a_1\)的倍数,还是\(b_1\)的因子
直接枚\(b_1\)的因子判是不是\(a_1\)的倍数并且满足俩式子就行了
0x03 码
#include<bits/stdc++.h>
using namespace std;
int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
int main(){
int t;
cin>>t;
while(t--){
int a1,a0,b0,b1,ans=0;
cin>>a0>>a1>>b0>>b1;
int p=a0/a1,q=b1/b0;
for(int i=1;i<=b1/i;i++)
if(b1%i==0){
if(i%a1==0&&gcd(i/a1,p)==1&&gcd(q,b1/i)==1) ans++;
if(b1/i==i) continue;
if((b1/i)%a1==0&&gcd((b1/i)/a1,p)==1&&gcd(q,b1/(b1/i))==1) ans++;
}
cout<<ans<<endl;
}
return 0;
}