1.普通的约数
任意一个大于等于2的整数n都可以表示为
n = (p1 ^ α1) * (p2 ^ α2) * (p3 ^ α3) ...... * (pk ^ αk)
其中p1,p2...pk为从小到大排列的质数
约数个数:对于乘积中的每一项,如果指数是 αk ,则有 (αk + 1)种选择方法。
由乘法原理:有约数的个数为 (α1 + 1) * (α2 + 1) ..... * (αk + 1)
约数之和:对于乘积中的每一项,如果指数是 αk ,则有 (αk + 1)种选择方法。如果指数选择的是p,则产生的数是 α ^ p。
故约数之和为 (p1 ^ 0 + p1 ^ 1 + ..... + p1 ^ α1) * ....... * (pk ^ 0 + pk ^ 1 + ..... + pk ^ αk)
2.最大公约数
前提知识:如果d|a && d|b 则有 d|(a*x+b*y) (定理1)
最大公约数的求法:欧几里得算法(辗转相除法)
代码如下:
int gcd(int a,int b)
{
return b?gcd(b, a%b) : a; //如果b是0,直接返回a(0可以被任何数整除)
}
正确性证明
为了证明上述代码,即证明 gcd(a,b) 和 gcd(b,a%b)有共同的最大公因数
有a % b = a - b * [a / b]。令c = [a / b]。
则a % b = a - c * b。
假设(a,b)的公因数为p。有p|a && p|b。对于等式右边,p也一定是b的公因数。
即证明 p 是 a % b 的公因数。
由于 a % b = a - c * b。由定理1可以得到:p|a%b。故p也是a % b的公因数
综上所述:gcd(a,b) = gcd(b,a%b)