数论初步-欧几里得算法

1 int judge(int* X) {
2 X[2] /= gcd(X[2], X[1]);
3 for(int i = 3; i <= k; i++) X[2] /= gcd(X[i], X[2]);
4 return X[2] == 1;
5 }

这个算法称为欧几里得算法。不会溢出,因为gcd函数的递归层数不超过4.785lgN + 1.6723,其N=max{a,b}gcd递归层数最多的是gcd(Fn,Fn-1)。利用gcd还可以求出两个整数a和b的最小公倍数lcm(a,b)。 这个结论很容易由唯一分解定理得到。由此不难验证gcd(a,b)*lcm(a,b)=a*b。

不过即使有了公式也不要大意。 如果把lcm写成a *b/gcd(a,b),可能会因此丢掉不少分数——a*b可能会溢出!正确的写法是先除后乘,即a/gcd(a,b) * b。 这样一来,只要题面上保证最终结果在int范围之内,这个函数就不会出错。
但前一份代码却不是这样:即使最终答案在int范围之内,也有可能中间过程越界。 注意这样的细节,毕竟算法竞赛不是数学竞赛。

posted @ 2016-04-21 19:51  mexbo  阅读(154)  评论(0)    收藏  举报