您的位置:首页 > 其它

2013年武科大蓝桥杯校内选拔赛 F gcd和lcm

2013-11-14 08:30 656 查看
基本思路还OK。。关键是我直接分解质因数 弄组合去了。。(而且我分解质因数由于素数打表有阴影,

从未成功实现过,所以我分解质因数开始也写的暴力十足= =)

没想到直接 k1、k2 互质,然后直接数个数n,输出2^n.

最后百无聊赖,各种搞不好,导致我去弄gcd函数暴力,很明显的超时。。

关键时刻我能说我 求最大公约数怎么写都忘了么T^T....我。。。

官方题解啦~

第6题:gcd和lcm

本题为基本数学题。

分析设a=k1*x,b=k2*x.则gcd(k1,k2)=1.且y=k1*k2*x 则k1*k2=y/x.

由于k1,k2互质,所以可以可以将y/x分解质因数。假设y/x=a1^b1*a2^b2*a3^b3….*an^bn

显然如果k1含有质因子ai,则k2一定不含因子ai,如果k1,k2同时含有相同因子的话,他们就不互质,可以推出矛盾。

所以k1,k2只可能含不同质因子,故只用统计y/x的质因子个数就可以了。

其种数为C(n,0)+C(n,1)+C(n,2)+…+C(n,n)=2^n.

解法:

用用o(n*lgn*lgn)的素数筛选法筛选素数,然后分解质因数,求出质因数个数n,最后输出2^n即可。总的时间复杂度o(n*lgn*lgn).

注意x不整除y的情况,直接输出0.

#include<cstdio>
#include<iostream>
#include<cstring>
#define M 1000010
using namespace std;

int s[32],cnt;
int isprime[M],prime[M];

void init()
{
s[0]=1;
for(int i=0;i<=30;i++)
s[i+1]=s[i]<<1;

memset(isprime,true,sizeof(isprime));
int nn=1000000;
cnt=0;

for(int i=2;i<=nn;i++)
{
if(isprime[i])
{
prime[++cnt]=i;
for(int j=i*2;j<=nn;j+=i)
isprime[j]=false;
}
}
}

int main()
{
int x,y;
init();

while(scanf("%d%d",&x,&y)!=EOF)
{
if(y%x)
{
printf("0\n");
continue;
}
int t=y/x;
int sum=0;

for(int i=1;prime[i]<t && i<cnt;i++)
{
if(t%prime[i]==0)
{
sum++;
while(t%prime[i]==0)
{
t=t/prime[i];
}
}
}
if(t!=1)
sum++;

printf("%d\n",s[sum]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: