对于lcm(b,x) = b1. 可以知道x是b1的一个约数。
解法1: 故可以取求d的所有约数然后判断是否同时满足两个条件。
求d的约数可以用dfs暴力来搞,这里要先把质数筛出来。
解法2:
假设b1通过唯一分解定理分解出来了所有质数。 对于每一个b1的质数p,假设a0,a1,b0,b1,x对应的个数为ma,ma1,mb,mb1,和 mx.
考虑 gcd(a,x) = a1: -> gcd就是求两个数进行唯一分解后所有相同质因子中次数最小的乘积
所以我们可以得到:
1: 当ma > ma1 时,mx = ma1
2: 当ma = ma1 时,mx >= ma
3: 当ma < ma1时,无解
考虑 lcm(b,x) = b1 -> lcm就是求两个数进行唯一分解后所有相同质因子中次数最多的乘积
1: 当mb > mb1 时, 无解
2: 当mb == mb1 时, mx <= mb
3: 当 mb < mb1 时,mx = mb1
为同时满足上面的条件,故将上面的条件合并一下,就可以得到某种条件下mx的取值了。最后做一个累乘就可以了。
最后得到的mx取值在f函数里面。
1代码:
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<bits/stdc++.h>
#define int long long
#define sc scanf
#define pf printf
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned long long LL;
const int INF = 0x3f3f3f3f;
const double eps = 1e-4;
const int mod = 998244353;
const int N = 100010;
bool book[N];
int primes[N],cnt;
pii factor[N];
int divd[N],cntd,cntf;
void dfs(int u,int p){//求出b1所有约数
if(u >= cntf){
divd[cntd++] = p;
return ;
}
for(int i=0;i<=factor[u].second;i++){
dfs(u+1,p);
p *= factor[u].first;
}
}
signed main(){
// IOS;
#ifdef ddgo
freopen("C:/Users/asus/Desktop/ddgoin.txt","r",stdin);
#endif
for(int i=2;i<=(int)sqrt(2e9);i++){
if(!book[i]){
primes[cnt++] = i;
for(int j=i;j*i<=(int)sqrt(2e9);j++) book[i*j] = true;
}
}
int tt; cin>>tt;
while(tt --){
int res = 0;cntd = cntf = 0;
int a,a1,b,b1;cin>>a>>a1>>b>>b1;
int bb = b1;
for(int i=0;i<cnt&&primes[i]*primes[i]<=b1;i++){//先把b1唯一分解后才好吧所有约数求出来
int x = primes[i];
if(b1 % x == 0){
int c = 0;
while(b1 % x == 0) c++,b1 /= x;
factor[cntf ++] = {x,c};
}
}
if(b1 > 1) factor[cntf++] = {b1,1};
dfs(0,1);
for(int i=0;i<cntd;i++){//判断两个条件
int x = divd[i];
if(__gcd(a,x) == a1 && b*x/(__gcd(b,x)) == bb)
res ++;
}
cout<<res<<endl;
}
return 0;
}
2 代码:
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<bits/stdc++.h>
#define int long long
#define sc scanf
#define pf printf
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned long long LL;
const int INF = 0x3f3f3f3f;
const double eps = 1e-4;
const int mod = 998244353;
const int N = 100010;
bool book[N];
int primes[N],cnt;
int f(int a,int b,int c,int d){
int k = 0;
if(a > b && c < d && b == d) k = 1;
else if(a > b && c == d && b <= d) k = 1;
else if(a == b && c < d && b <= d) k = 1;
else if(a == b && c == d && b <= d) k = d-b+1;
return k;
}
int ff(int m,int x){
int c = 0;
while(m % x == 0) c++,m /= x;
return c;
}
signed main(){
// IOS;
#ifdef ddgo
freopen("C:/Users/asus/Desktop/ddgoin.txt","r",stdin);
#endif
for(int i=2;i<=(int)sqrt(2e9);i++){//先把质数筛出来
if(!book[i]){
primes[cnt++] = i;
for(int j=i;j*i<=(int)sqrt(2e9);j++) book[i*j] = true;
}
}
int tt; cin>>tt;
while(tt --){
int res = 1;
int a,a1,b,b1;cin>>a>>a1>>b>>b1;
for(int i=0;i<cnt&&primes[i]*primes[i]<=b1;i++){//分解b1的质因数
int x = primes[i];
if(b1 % x == 0){
int c = 0;
while(b1 % x == 0) c ++,b1 /= x;
int ma = ff(a,x),ma1=ff(a1,x),mb=ff(b,x);
res *= f(ma,ma1,mb,c);
}
}
if(b1 > 1){
int ma = ff(a,b1),ma1=ff(a1,b1),mb=ff(b,b1);
res *= f(ma,ma1,mb,1);
}
cout<<res<<endl;
}
return 0;
}