确定每一个质因子的指数取值范围即可.
#include <iostream>
#include <vector>
#include <cassert>
#include <numeric>
#include <map>
#include <set>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
constexpr int N = 4e4 + 10;
vector<int> primes{};
map<int,int> prime_cnts[4];
set<int> prime_set;
bool test[N];
void init(){
primes.reserve(N / 5);
for(long long i = 2; i < N ; ++i) {
if(test[i]) continue ;
primes.push_back(i);
for(auto j = i * i ; j < N ; j += i ) test[j] = true;
}
}
void factoring(int n , int j){
for(int i : primes){
if(i * i > n) break;
int c = 0;
while(n % i == 0) n /= i , ++c;
if(c) prime_cnts[j][i] = c , prime_set.insert(i);
}
if(n > 1) {
prime_set.insert(n);
prime_cnts[j][n] = 1;
}
}
void reset(){
for(auto & ps : prime_cnts) ps.clear();
prime_set.clear();
}
int main(){
int n ; cin >> n;
init();
while(n--){
int a1 , a0 , b1 , b0 ; cin >> a0 >> a1 >> b0 >> b1;
reset();
factoring(a0 , 0);
factoring(a1 , 1);
factoring(b0 , 2);
factoring(b1 , 3);
auto get_count_in_p = [](int ca0 , int ca1 , int cb0 , int cb1){
int left = 0 , right = numeric_limits<int>::max() - 1;
// assert(ca0 >= ca1);
if(ca0 == ca1) left = max(left , ca1);
else left = max(left , ca1) , right= min(right , ca1);
// assert(cb0 <= cb1) ;
if(cb0 == cb1) right = min(right , cb1);
else left = max(left , cb1) , right = min(right , cb1);
return max(0 , right - left + 1);
};
int ans = 1;
for(int p : prime_set){
if(ans == 0) break;
int ca0 = prime_cnts[0][p];
int ca1 = prime_cnts[1][p];
int cb0 = prime_cnts[2][p];
int cb1 = prime_cnts[3][p];
ans *= get_count_in_p(ca0 , ca1 , cb0 , cb1);
}
cout << ans << endl;
}
}