注意下面三个式子,它可以保证在计算中不会发生溢出。
(a+b) mod m=(a mod m+b mod m) mod m
(a-b) mod m=(a mod m-b mod m+m) mod m
(ab) mod m=(a mod m)×(b mod m) mod m
求最大公约数只需用欧几里得算法(辗转相除法)。
求最小公倍数需要用到最大公约数与最小公倍数的关系:
可以看到,程序先做除法后做乘法,这样可防止计算过程中发生溢出。
- int gcd(int a, int b) { return (b==0) ? a : gcd(b, a%b); }
- int lcm(int a, int b) { return a / gcd(a,b) * b; }
让 gcd 运算次数最多的一对数是斐波那契数。即使这样,gcd 也不会爆栈。
gcd 可以改写成非递归算法:
- int gcd(int a, int b)
- {
- int t=a%b;
- while(t)
- {
- a=b;
- b=t;
- t=a%b;
- }
- return b;
- }