题解:各种质因数分解然后处理每一种质因数对于答案的最大个数和最小个数。
1.用d处理一个上界出来
2.用d/c处理一个下界出来
3.用b处理一个下界出来
4.用a处理一个上界出来
5.ans跑一遍,各种乘,然后出解。
P.S. 顺序自己调整,或者不怕麻烦就开一堆上界和下界,要输出时整合。
当然,也可以看我代码的处理顺序。
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 50
using namespace std;
struct DI
{
int up,down,x,up2;
}s[N];
int a,b,c,d,cnt;
int main()
{
// freopen("test.in","r",stdin);
int i,j,k,temp,g;
scanf("%d",&g);
while(g--)
{
cnt=0;
scanf("%d%d%d%d",&a,&b,&c,&d);
temp=d;
for(i=2;i*i<=temp;i++)
{
if(temp%i==0)
{
cnt++;
s[cnt].x=i;
s[cnt].up=1;/*上界是开区间*/
s[cnt].down=0;
while(temp%i==0)
{
temp/=i;
s[cnt].up++;
}
}
}
if(temp>1)
{
cnt++;
s[cnt].x=temp;
s[cnt].up=2;
s[cnt].down=0;
}
/*分解d完成。*/
temp=b;
for(i=1;i<=cnt;i++)
{
if(temp%s[i].x==0)
{
while(temp%s[i].x==0)
{
temp/=s[i].x;
s[i].down++;
}
}
}
if(temp>1)
{
puts("0");
continue;
}
/*下界是闭区间,,,额,分解完b了,if(d%b),你懂的。*/
temp=a/b;
for(i=1;i<=cnt;i++)if(temp%s[i].x==0)
{
//s[i].up=min(s[i].up,s[i].down+1); 实际可以把这行写成下面一行
s[i].up2=s[i].down+1;
}
/*根据a/b确定一些上界*/
temp=d/c;
for(i=1;i<=cnt;i++)if(temp%s[i].x==0)
{
s[i].down=max(s[i].down,s[i].up-1);
}
/*c和d都用完了~~*/
int ans=1;
for(i=1;i<=cnt;i++)
{
if(s[i].up2)s[i].up=s[i].up2,s[i].up2=0;
if(s[i].up<=s[i].down)s[i].up=s[i].down;
ans*=(s[i].up-s[i].down);
}
printf("%d\n",ans);
}
fclose(stdin);
fclose(stdout);
return 0;
}