题目链接:https://www.luogu.org/problemnew/show/P1072
显然,这是一道小学奥数题数论题。
考虑暴力枚举的话,从1枚举到b1,再有2000组数据,很显然会TLE。
由于两数的最大公约数分解质因数后每一项的次数都一定小于等于原来两数的次数;最小公倍数分解质因数后每一项的次数都一定大于等于原来两数的次数,所以考虑将输入分解质因数,接着根据这四个数分解质因数后每一项的指数确定x的每一项的指数的范围。
#include<bits/stdc++.h>
using namespace std;
typedef map<long long,int> zysmap;//用于存储分解质因数的结果
long long min_(long long a,long long b){//由于原来是0又要特判,自己写了一个伪·min
if(a==0)return b;
if(b==0)return a;
if(a>b)return b;
else return a;
}
void fjzys(long long n,zysmap &zys){//分解质因数
zys.clear();
for(int i=2;i<=sqrt(n);i++){
while(n%i==0){
zys[i]++;
n/=i;
}
if(n==1)return;
}
if(n!=1){
zys[n]++;
}
}
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
long long a0,a1,b0,b1,xzys=1;//四个数与答案
cin>>a0>>a1>>b0>>b1;
map<long long,pair<long long,long long> >xxz;//x指数的范围
zysmap a0zys,a1zys,b0zys,b1zys;//分解质因数的结果
fjzys(a0,a0zys);//分解
fjzys(a1,a1zys);//分解
fjzys(b0,b0zys);
fjzys(b1,b1zys);
for(zysmap::iterator j=a0zys.begin();j!=a0zys.end();j++){//判断范围
if(a1zys[j->first]>j->second){//不科学的结果,肯定为0
xzys=0;
} else if(a1zys[j->first]==j->second){//有下限,没有上限
xxz[j->first].first=a1zys[j->first];
xxz[j->first].second=9223372036854775807;
} else{//有下限,有上限
xxz[j->first].first=a1zys[j->first];
xxz[j->first].second=a1zys[j->first];
}
}
for(zysmap::iterator j=b1zys.begin();j!=b1zys.end();j++){
if(b0zys[j->first]<j->second){
if(xxz.count(j->first)){//如果已有结果,取限制最严者
xxz[j->first].first=max((long long)j->second,xxz[j->first].first);
xxz[j->first].second=min(xxz[j->first].second,(long long)j->second);
}else{//直接记录范围
xxz[j->first].first=(long long)j->second;
xxz[j->first].second=(long long)j->second;
}
} else if(b0zys[j->first]==j->second){
if(xxz.count(j->first)){//同理
xxz[j->first].first=max(xxz[j->first].first,(long long)-1);
xxz[j->first].second=min(xxz[j->first].second,(long long)j->second);
}else{
xxz[j->first].second=(long long)j->second;
}
} else{//不科学的结果,肯定为0
xzys=0;
}
}
for(map<long long,pair<long long,long long> >::iterator j=xxz.begin();j!=xxz.end();j++){//根据限制,利用乘法原理算出结果
if(j->second.first<=j->second.second){
xzys*=j->second.second-j->second.first+1;
}else{
xzys=0;
}
}
cout<<xzys<<endl;
}
return 0;
}