题目
题解思路
x肯定是b1的约数,所以从这里入手(我是想不到)。
直接枚举所有约数如果符号上面的条件就可以作为答案。
根号D2e3
这样的话复杂度大概5e42e3 大概1亿左右,这样是很有可能超时的。
时间复杂度已经接近了,只要稍微优化一下就行了。
大概在5e3*2e3 1e7
筛出质数后。
我们直接枚举所有质数,以及它的次数。
我们只在D的质因子下枚举。
这样直接用dfs暴力枚举出它的约数,约数个数(这一步可以减少大量dfs的次数)不会超过1600的。dfs的次数最多1600,所以可以忽略复杂度。
这样就能过了。
AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
#include <unordered_map>
using namespace std;
const int INF = 0x3f3f3f3f;
bool pr[50100] ;
int prm[50100] ;
int cnt = 1 ;
struct node
{
int z,s;
};
vector <node> zs;
long long a0 ,a1 , b0, b1 ;
int ans = 0 ;
void in()
{
pr[1] = 1 ;
for (int i = 2 ; i <= 50000 ; i++ )
{
if ( ! pr[i] )
{
prm[cnt] = i ;
cnt++;
for (int j = i*2 ; j <= 50000 ; j+= i )
{
pr[j] = 1 ;
}
}
}
}
void dfs(int p , long long k )
{
if ( p >= zs.size() )
{
if ( __gcd(k , a0) == a1 && k*b0/__gcd(k,b0) == b1 )
{
// cout<<k<<"\n";
ans++;
}
return ;
}
for (int i = 0 ; i <= zs[p].s ; i++ )
{
dfs(p+1,k);
if ( k*zs[p].z > b1 )
return ;
k*=zs[p].z;
}
}
int main ()
{
ios::sync_with_stdio(false);
in();
int T;
cin >> T ;
while( T-- )
{
zs.clear();
ans = 0 ;
cin >> a0 >> a1 >> b0 >> b1 ;
int d = b1 ;
for (int i = 1 ; prm[i] <= d/ prm[i] ; i++ )
{
int p = prm[i] ;
if ( b1 % p == 0 )
{
int s = 0;
while(d%p == 0 )
{
d /= p ;
s++;
}
zs.push_back({p,s});
}
}
if ( d > 1 )
zs.push_back({d,1});
dfs(0,1);
cout<<ans<<"\n";
}
return 0 ;
}