您的位置:首页 > 其它

【NOIP2009】洛谷1072 Hankson的趣味题

2016-08-21 20:27 232 查看
题目描述

Hanks 博士是 BT (Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫 Hankson。现

在,刚刚放学回家的 Hankson 正在思考一个有趣的问题。

今天在课堂上,老师讲解了如何求两个正整数 c1 和 c2 的最大公约数和最小公倍数。现

在 Hankson 认为自己已经熟练地掌握了这些知识,他开始思考一个“求公约数”和“求公

倍数”之类问题的“逆问题”,这个问题是这样的:已知正整数 a0,a1,b0,b1,设某未知正整

数 x 满足:

1. x 和 a0 的最大公约数是 a1;

2. x 和 b0 的最小公倍数是 b1。

Hankson 的“逆问题”就是求出满足条件的正整数 x。但稍加思索之后,他发现这样的

x 并不唯一,甚至可能不存在。因此他转而开始考虑如何求解满足条件的 x 的个数。请你帮

助他编程求解这个问题。 输入输出格式 输入格式:

第一行为一个正整数 n,表示有 n 组输入数据。接下来的 n 行每

行一组输入数据,为四个正整数 a0,a1,b0,b1,每两个整数之间用一个空格隔开。输入

数据保证 a0 能被 a1 整除,b1 能被 b0 整除。

输出格式:

输出文件 son.out 共 n 行。每组输入数据的输出结果占一行,为一个整数。

对于每组数据:若不存在这样的 x,请输出 0;

若存在这样的 x,请输出满足条件的 x 的个数;

一种显而易见的做法是将四个数质因数分解。然后对于某一个质因数p,设四个数的指数分别为ta0,ta1,tb0,tb1。则所求数的指数x满足:

x=ta1(ta0< ta1)

x>=ta1(ta0=ta1)

x∈∅(ta0< ta1)

x=tb1(tb0< tb1)

x<=tb1(tb1=tb0)

x∈∅(tb0> tb1)

由这些条件不难出解。

在进行质因数分解的时候,如果直接循环找因数可能超时。考虑到一个数大于1e5的因数最多只有一个,可以先筛出1..1e5之内的素数逐一计算,然后对大于1e5的因数再进行单独判断。

#include<cstdio>
#include<cstring>
int ta0[10000],ta1[10000],tb0[10000],tb1[10000],prm[10000];
bool have[100000];
int main()
{
//freopen("son.in","r",stdin);
//freopen("son.out","w",stdout);
int i,j,k,m,n,x,y,z,a0,a1,b0,b1,cnt,T,tot=0,totnew;
long long ans;
bool flag;
for (i=2;i<=100000;i++)
{
if (!have[i]) prm[++tot]=i;
for (j=1;(long long)i*prm[j]<=100000;j++)
{
have[i*prm[j]]=1;
if (i%prm[j]==0) break;
}
}
scanf("%d",&T);
while (T--)
{
scanf("%d%d%d%d",&a0,&a1,&b0,&b1);
memset(ta0,0,sizeof(ta0));
memset(ta1,0,sizeof(ta1));
memset(tb0,0,sizeof(tb0));
memset(tb1,0,sizeof(tb1));
n=0;
flag=1;
for (i=1;i<=tot&&(a0>1||a1>1||b0>1||b1>1);i++)
if (a0%prm[i]==0||a1%prm[i]==0||b0%prm[i]==0||b1%prm[i]==0)
{
n++;
while (a0%prm[i]==0)
{
a0/=prm[i];
ta0
++;
}
while (a1%prm[i]==0)
{
a1/=prm[i];
ta1
++;
}
while (b0%prm[i]==0)
{
b0/=prm[i];
tb0
++;
}
while (b1%prm[i]==0)
{
b1/=prm[i];
tb1
++;
}
}
if (a0>1)
{
n++;
ta0
=1;
if (a1==a0)
{
ta1
=1;
a1=1;
}
if (b0==a0)
{
tb0
=1;
b0=1;
}
if (b1==a0)
{
tb1
=1;
b1=1;
}
}
if (a1>1)
{
n++;
ta1
=1;
if (b0==a1)
{
tb0
=1;
b0=1;
}
if (b1==a1)
{
tb1
=1;
b1=1;
}
}
if (b0>1)
{
n++;
tb0
=1;
if (b1==b0)
{
tb1
=1;
b1=1;
}
}
if (b1>1)
{
n++;
tb1
=1;
}
flag=0;
for (i=1;i<=n;i++)
if (ta0[i]<ta1[i]||tb0[i]>tb1[i])
{
printf("0\n");
flag=1;
break;
}
if (flag) continue;
ans=1;
for (i=1;i<=n;i++)
if (ta0[i]>ta1[i])
{
if (tb0[i]<tb1[i])
{
if (ta1[i]==tb1[i]) continue;
else
{
ans=0;
break;
}
}
else
{
if (ta1[i]<=tb1[i]) continue;
else
{
ans=0;
break;
}
}
}
else
{
if (tb0[i]<tb1[i])
{
if (tb1[i]>=ta1[i]) continue;
else
{
ans=0;
break;
}
}
else ans*=(tb1[i]-ta1[i]+1);
}
printf("%lld\n",ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  质因数分解