本题挺经典的,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 long int 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; }