这又是一道省选的数学题,由于本蒟蒻数学很烂,在此不给出详细的证明过程,只是简述下目标和结论;
如果我们想证的话,可以证明出:
如果gcd(x,a0)=a1,那么gcd(x/a1,a0/a1) (可以往最大公约数的性质方面考虑,如果除出来的数还不互质,证明原数一定不是最大公约数)
此外:这里引用学长证明
然后发现,b1一定是x的整倍数,而x一定是a1的整倍数,所以可以采取枚举b1的因子;
上代码
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<cstring> 6 #include<string> 7 #include<algorithm> 8 #include<queue> 9 #include<bitset> 10 #include<set> 11 using namespace std; 12 int gcd(int a,int b){return b==0 ? a:gcd(b,a%b);}//辗转相除法 13 int main() 14 { 15 int T; 16 scanf("%d",&T); 17 while(T--){ 18 int a0,a1,b0,b1; 19 scanf("%d%d%d%d",&a0,&a1,&b0,&b1); 20 int p=b1/b0,q=a0/a1,ans=0; 21 for(int x=1;x*x<=b1;x++){ 22 if(b1%x!=0) continue;//枚举到的必须是b1的因子 23 if(x%a1==0&&gcd(q,x/a1)==1&&gcd(p,b1/x)==1) ans++; 24 int y=b1/x;//找到第二个因子,借此来简化计算 25 if(x==y) continue;//找重了排除掉 26 if(y%a1==0&&gcd(q,y/a1)==1&&gcd(p,b1/y)==1) ans++; 27 } 28 cout<<ans<<endl; 29 } 30 return 0; 31 }