一个大于1的正整数肯定能被分成一系列素数的和,因为合数可以由素数相乘得到。 所以 n=p1^a1 * p2^a2 . . .*pn^an(pi 为素数)。
经过思考可以得出
1.求n的因数的个数。
(1+a1)(1+a2)(1+a3)(1+a4)…(1+an)(ai 为素因数的幂);
p1^a1是n的因数,那么p1 ^(0~a1)都是n的因数,相乘求出所以可能。
(大概是这样吧。。。)
2.求n的因数之和
sum=(q1^ 0+q1^ 1+q1^ 2…q1^ a1)(q2^ 0+q2^ 1+q2^ 2…q2^ a2)…*(qn^ 0+qn^ n+qn^ 2 …qn^ an);
总结:
一开始以为这个定理没啥用(还是太弱了qaq),我以为按暴力的方法是√n的复杂的,这个唯一分解定理最短应该也是个O(n),开始以为自己的方法很完美,结果。。。。
求因子个数代码如下
while(~scanf("%lld",&a))
{
ll ans =0;
for(int i=1;i*i<=a;i++)
{
if(a%i==0)
{
if(i!=a/i)
ans +=i+a/i; //知道一个因数用n除这个因数即可得到另一个因数,n =√n*√n,遍历这一半即可得到另一半不会遗漏。
else
ans +=i;
ans %=mod;
}
}
printf("%lld\n",ans%mod);
}
当我遇到这题的时候突然明白了唯一分解定理的用处。
POJ - 1845 G - Sumdiv。问题链接
a^b次方太大,我们无法直接求出n,如果在求a ^b次方的过程中取模,会有精度损失,如果用唯一分解定理分解就不会有这种问题。