整除
【定义】 对于,如果有
使得
,则称
整除
,记为
.
关于整除有如下结论:
- 若
,
,且
,则
.
最大公因子
【定义】 所有同时整除和
的整数中,最大的那个,称为
和
的最大公因子,记为
,也可记为
.
【引理】 设,这里
,则
.
证明:由于
,所有
和
的公因子同时整除
和
,所以也能整除
,所以也是
和
的公因子。由于
,所有
和
的公因子同时整除
和
,所以也能整除
,所以也是
和
的公因子。也就是说,
和
的公因子,
和
的公因子是同一拨,那么
和
的公因子中最大的那个,
和
的公因子中最大的那个 当然是同一个了。 所以
。
欧几里得算法
欧几里德算法又称辗转相除法,是指用于计算两个正整数和
的最大公因子。证明过程主要依据上面的引理
。
代码实现如下:
#include<algorithm>
#include<iostream>
/*
欧几里德算法:辗转求余
原理: gcd(a,b)=gcd(b,a mod b)
当b为0时,两数的最大公约数即为a
*/
int gcd(int a, int b){
if (a < b){
std::swap(a, b);
}
if (0 == b){
return a;
}else{
return gcd(b, a % b);
}
}
// 简单测试
int main() {
int t = gcd(10,25);
std::cout<<t;
}
扩展欧几里得算法
【定义】 对于,我们称
为
的整系数线性组合,并用
表示它们构成的集合。
【扩展欧几里得算法】 设和
是两个正整数(至少有一个非零),
,则存在整数
和
使得
成立,如果
和
都是素数,那么存在整数
和
使得
成立。
代码实现:
def egcd(a,b):
if 0 == b:
return a,1,0
gcd,k1,k2 = egcd(b, a%b)
return gcd,k2,k1-a/b*k2
互素
最大公因子的最小可能取值是,当
,即
和
的最大公因子为
时,我们称
和
互素。
乘法逆元
当时,有时候我们很希望求得一个数
,
,使
,这样的数我们称为
的乘法逆元,
这看起来就像是在
到
这些整数中找到
的倒数一样。那怎么找到这样的数呢?
扩展欧几里得算法可以帮我们解决这个问题。
由于,根据扩展欧几里得算法,可求得两个系数
和
,使得
,所以有
,所以
,所以
,而
,所以
就是我们想要的那个乘法逆元。
算数基本定理
【算数基本定理(整数的唯一分解定理)】任何大于的整数
可表示成有限个(可重复)素数的乘积,而且不计乘积中因子顺序时分解还是唯一的。
根据算数基本定理,大于的整数
唯一地表示成
的形式,这里
为不同素数,
,我们称这样的形式为
的标准(素数)分解式。
欧拉函数
对任意一个正整数,在
到
的这 个整数里,显然有些和
是互素的,而有些和
是不互素的,那些和
互素的整数
的数量就是
的欧拉函数,记作
。
那么该怎么计算呢?
我们都知道任意整数都可以表示成它的所有素因子的乘积:
所以所有那些和不互素的数,一定和
有其中某个素因子作为公共因子。所以我们只要从
到
中的所有整数中,是
的倍数的依次剔除,剩下的就是与
互素的数。
例如,的倍数一共有多少个呢,由于
的倍数在
到
中是均匀分布的,所以占据的比例是
,剔除
的倍数后,还剩下
个;在剩下的数中,由于
的倍数在
到
中也是均匀分布的,所以占据的比例是
,所以再剔除
的倍数后,剩下
个。以此类推,当把所有素因子的整数倍都剔除后,剩下的数共有
个。即:
$
由此可见,求欧拉函数的关键在于求出的所有素因子,即对
做素因子分解。
有一种特殊情况,为素数,那么
仅有一个素因子,即它自己。此时
。
还有一种特殊情况,仅有两个素因子,即
,那么
。如果已知
和
,显然
是好求的;而如果仅知道
,而不知道
和
,那么必须要先对
做素因子分解,得到
和
,才能求得
。
如果这两个素因子都极大,那么当然
也就极大。要从
到
这
个数中找出这两个素因子,就如同大海捞针,复杂度极高。
丢番图方程
古希腊数学家丢番图首次系统地研究了方程的整数解问题,现在涉及整数解的方程都叫做丢番图方程,也叫不定方程。
丢番图方程,又称不定方程,是未知数只能使用整数的整数系数多项式等式;即形式如的等式,并且其中所有的
,
和
均是整数。若其中能找到一组整数解
,
者则称之为有整数解。线性丢番图方程为线性整数系数多项式等式,即此多项式为次数为
或
的单项式的和。
【定理】设,则线性丢番图方程
有整数解当且仅当
.
贝祖等式
对任何整數和
,关于未知数
和
的线性丢番图方程(称为贝祖等式):
.有整数解时当且仅当
是
和
的最大公约数
的倍数,即
.