- 这次看看数论的内容,之前本来想把这部分交给队员的,不过队员太忙了,还是我来看吧。。。
- 先回顾一下欧几里得算法和扩展欧几里得算法吧
欧几里得算法
核心内容
- gcd(a,b) = gcd(b,a % b)
- gcd(a,b) = gcd(b,a)
- a % 0 = a
简单证明
a=b∗c+r,r=a%ba = b * c + r, \quad r = a \% ba=b∗c+r,r=a%b
设 ddd 是 aaa,bbb最大公约数,则ddd也是a−b×c=ra - b \times c = ra−b×c=r的约数,所以d也是b和r的公约数。
接下来说明ddd是bbb和rrr的最大公约数,假设存在d′>dd' > dd′>d,且d′d'd′也是bbb和rrr的公约数,则d′d'd′ 也是 r+b×c=ar + b \times c = ar+b×c=a的约数,那么d′d'd′也就是aaa,bbb的公约数,这与ddd是aaa,bbb最大公约数矛盾,得证。
实现
int gcd(int a,int b){
if (b == 0) return a;
return gcd(b,a%b);
}
扩展欧几里得算法
注:这里只讨论一些对算法的理解,先不考虑活用
核心内容
- 对于非负整数且不全为0的整数a和b,存在整数x和y,使得ax + by = gcd(a , b)成立。
- 若ax + by = c,且 c不能整除gcd(a , b),那么该方程x和y不存在整数解
简单证明和推导
- 核心内容的证明还没有深入研究,这里先放一放,和比赛相关性较小,以后有机会再看。
- 算法的推导:
- ax + by = gcd(a, b)
- 根据欧几里得算法有:
bx’ + (a % b)y’ = gcd(b, a % b) = gcd(a, b) - 有a % b = a - (a / b) * b //注意这里除是整数除,即下取整
- 所以有 bx’ + (a - (a / b) * b)y’ = gcd(a,b)
- 整理得 ay’ + b(x’ - a/b * y’) = gcd(a , b)
- 因此有x = y’ 且 有y = x’ - a/b * y’
- 另一方面,当b = 0时, x = 1且y = 0
- 根据以上推导,就不难写出一套递归的算法了
实现
int extgcd(int a,int b,int& x,int& y){
if (b != 0){
int ret = extgcd(b,a%b,y,x);
//y计算之前 = x', x = y'
y -= a / b * x;
return ret;
}
else{
x = 1, y = 0;
return a;
}
}