题意是给abcd四个数,求有多少个x满足gcd(a,x)==b,lcm(c,x)==d.
由于lcm(c,x)==d,所以x一定是d的约数,所以可以求出d的所有约数再判断是否符合条件。
第一种:试除法求约数,会超时。
第二种:筛出1 - sqrt d 的所有质数,再爆搜出d的所有约数判断是否符合条件。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
const int N = 45000;
int prime[N],idx,a,b,c,d,n,z,tt,ans;
bool st[N];
pii fa[N];
int arr[N];
void get_prime(int n)
{
for(int i = 2; i <= n; i ++ )
{
if(!st[i])
prime[idx ++ ] = i;
for(int j = 0; prime[j] * i <= n; j ++ )
{
st[prime[j] * i] = true;
if(i % prime[j] == 0)
break;
}
}
}
int gcd(int a, int b)
{
return b? gcd(b,a % b) : a;
}
void dfs(int u,int p)//u代表第u个质因数组,p代表当前约数
{
if(u > z)
{
arr[tt ++ ] = p;
return ;
}
for(int i = 0; i <= fa[u].second; i ++ )
{
dfs(u + 1,p);
p *= fa[u].first;
}
}
int main()
{
get_prime(N);
cin>>n;
while(n -- )
{
cin>>a>>b>>c>>d;
int x = d;
z = 0;
ans = 0;
tt = 0;
for(int i = 0; prime[i] <= x / prime[i]; i ++ )//对每个质因数分解,将质数和数量存入pii
{
int p = prime[i];
int s = 0;
if(x % p != 0)
continue;
while(x % p == 0)
{
s ++;
x /= p;
}
fa[++ z] = {p,s};
}
if(x > 1)
fa[++ z] = {x,1};
dfs(1,1);//暴搜
for(int i = 0; i < tt; i ++ )//判断
{
int num = arr[i];
if(gcd(num,a) == b && (ll)num * c / gcd(num, c) == d)
ans ++;
}
cout<<ans<<endl;
}
return 0;
}