UVa 10892 LCM Cardinality (分解质因数+数学)

来源:互联网 发布:linux终端输入密码 编辑:程序博客网 时间:2024/06/05 10:12

本题挺经典的,sqrt(n)时间复杂度分解质因数。

先看一个公式,数字a=p1^a1*p2^a2*p3^a3.........,b=p1^b1*p2^b2*p3^b3(其中pi为质因数,ai,bi为幂次),那么他们的LCM c=p1^max(a1,b1)*p2^max(a2,b2)..........,同理gcd是取每个质因数幂次最小值。


这样,如果lcm:c确定了,且c=p1^c1*p2^c2*p3^c3.........,那么得到他的两个数a,b中,对于每个pi,a,b中一个数的pi的幂次等于c1,另一个小于等于c1,这样对于每个pi,a的幂次为ci时b可以是0~ci-1,b为ci时a同理,再加上a,b同为ci的情况,对于每个pi方案数就是2*c1+1,把这些数乘法原理乘起来,除了(c,c)这组数,每个数都出现了2次,所以最后结果除2加1。


剩下的问题就是如何对10^9大小的数分解质因数。

遍历到根号n,对每个能整除n的数都一直除,这样根号n一下的质因子肯定都处理完了。可以证明,大于根号n的质因子至多有一个,且它的幂次为1。

证明:设p1,p2是n的质因子,且都大于根号n,那么n>=p1*p2,所有p1,p2不可能都大于根号n。


这样遍历到根号n后,只要判断下除剩下的n是不是等于1,大于一就说明还有一个大质数,再把结果乘3。


代码:

#include <iostream>#include <cstdio>#include <cstring>using namespace std;#include <algorithm>#define LL long longint N;int main(){while(~scanf("%d",&N)){int k=N;LL res=1;if(!N) break;for(int i=2;i*i<=N;i+=2){int tmp=1;while(N%i==0){tmp++;N/=i;}res*=(2*tmp-1);if(i==2) i--;}if(N>1) res*=3;res/=2;res+=1;printf("%d %lld\n",k,res);}return 0;}


0 0
原创粉丝点击