对于是否存在需要进行一些判断:
1、如果a0%a1 !=0 or b1%b0!=0 那么输出0。
然后我们将a0,a1,b0,b1存入四个map,A0,A1,B0,B1
中,在用一个总map记录所有的因子种类。
对于每一个因子种类我们需要进行以下判断:
(此后说的“最小”,“最大”,A0,A1等都指的是对于当前的质因数的出现次数。)
1、找到最小出现次数和最大出现次数,那么X的取值就是在这个区间内(包含边界)。
2、判断是否“最小”大于“最大”,即A0是否大于等于A1,B0是否小于等于B1。
3、如果A0不等于最小,说明X必须为最小,但这并不说明B0为最大,也有可能B0小于B1但最小等于最大。
4、如果B0不等于最大,那么X必须要等于最大,但A0不一定要等于最小,A0可以大于最小,前提是最小等于最大。
附上我的AC代码:
#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize(2)
#define ll long long
#define PII pair<int,int>
#define endl "\n"
#define INF 1e18
#define int long long
const int N = 1000005; // 1e6 + 5
//對x進行整數分解
map<int,int> get(int x){
map<int,int> t;
for(int i = 2; i * i <= x; i++){
while(x%i == 0){
x/=i;
t[i]++;
}
}
if(x > 1) t[x] ++;
return t;
}
void print(map<int,int> &t){
for(auto i : t){
cout << i.first << ' ' << i.second << endl;
}
cout << endl;
}
void solve() {
map<int,int> A0,A1,B0,B1,m;
int a0,a1,b0,b1;
cin >> a0 >> a1 >> b0 >> b1;
if(a0 % a1 != 0 or b1%b0 != 0) {
cout << 0 << endl;
return;
}
A0 = get(a0); A1 = get(a1); B0 = get(b0); B1 = get(b1);
/*
print(A0);
print(A1);
print(B0);
print(B1);
*/
//將裏面所有的質因數種類放入m中。
for(auto i : A0) m[i.first] = 1; for(auto i : A1) m[i.first] = 1;
for(auto i : B0) m[i.first] = 1; for(auto i : B1) m[i.first] = 1;
int ans = 1;
for(auto i : m){
int yz = i.first;
int min_yz = A1[yz];
int max_yz = B1[yz];
if(min_yz > max_yz or A0[yz] < A1[yz] or B0[yz] > B1[yz]) {
cout << 0 << endl; return;
}
//第一种情况,A0的因子是最小因子,B0的因子是最大因子
//那么x的因子可以取值它们两个之间
if(A0[yz] == min_yz and B0[yz] == max_yz){
ans*= (max_yz - min_yz + 1);
}
//第二种情况,A0的因子不是最小因子,所以X必须是最小因子
//此时要么B0是最大因子,要么X是最大因子,即最小因子等于最大因子
else if(A0[yz] != min_yz and (B0[yz] == max_yz or min_yz == max_yz)){
ans*=1;
}
//第三种情况,B0因子不是最大因子,此时X是最大因子,如果A0不是最小因子,那么最大因子等于最小因子
else if((A0[yz] == min_yz or min_yz == max_yz) and B0[yz] < max_yz){
ans*=1;
}
else{
cout << 0 << endl;
return;
}
}
cout << ans << endl;
}
signed main () {
std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int t;
cin>> t;
while(t --)
solve();
}