数论——算数基本定理、欧几里得算法、丢番图方程

485 阅读5分钟

整除

【定义】 对于a,b \in Z,如果有q \in Z使得aq=b,则称a整除b,记为a|b.

关于整除有如下结论:

  • c=k_1a+k_2be|a,且e|b,则e|c.

最大公因子

【定义】 所有同时整除ab的整数中,最大的那个,称为ab的最大公因子,记为 (a,b),也可记为gcd(a,b).

【引理】 设a=bq+c,这里a,b,c,q\in Z,则(a,b)=(b,c).

证明:由于a=bq+c,所有bc的公因子同时整除bc ,所以也能整除a,所以也是ab的公因子。由于c=a-bq,所有ab的公因子同时整除ab ,所以也能整除c,所以也是bc的公因子。也就是说,ab的公因子,bc的公因子是同一拨,那么ab的公因子中最大的那个,bc的公因子中最大的那个 当然是同一个了。 所以(a,b)=(b,c)

欧几里得算法

欧几里德算法又称辗转相除法,是指用于计算两个正整数ab的最大公因子。证明过程主要依据上面的引理(a,b)=(b,c)

代码实现如下:

#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;
}

扩展欧几里得算法

【定义】 对于a_1,\cdots,a_n\in Z,我们称a_1x_1+ \cdots + a_nx_n(x_1,\cdots,x_n\in Z)a_1,\cdots,a_n的整系数线性组合,并用a_1Z+\cdots+a_nZ表示它们构成的集合。

【扩展欧几里得算法】 设ab是两个正整数(至少有一个非零),d=gcd(a,b),则存在整数xy使得ax+by=d成立,如果ab都是素数,那么存在整数xy使得ax+by=1成立。

代码实现:

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

互素

最大公因子的最小可能取值是1,当(a,b)=1ab的最大公因子为1时,我们称ab互素。

乘法逆元

(a,b)=1时,有时候我们很希望求得一个数k0\leq k \lt b,使ka\ mod\ b=1 ,这样的数我们称为a的乘法逆元, 这看起来就像是在0b-1这些整数中找到 a的倒数一样。那怎么找到这样的数呢?

扩展欧几里得算法可以帮我们解决这个问题。

由于(a,b)=1,根据扩展欧几里得算法,可求得两个系数k_1k_2,使得k_1a+k_2b=(a,b)=1,所以有k_1a=-k_2b+1,所以k_1a\ mod\ b=1 ,所以(k_1\ mod\ b)a\ mod\ b=1,而0\leq(k_1\ mod\ b)\lt b,所以(k_1\ mod\ b)就是我们想要的那个乘法逆元。

算数基本定理

【算数基本定理(整数的唯一分解定理)】任何大于1的整数n可表示成有限个(可重复)素数的乘积,而且不计乘积中因子顺序时分解还是唯一的。

根据算数基本定理,大于1的整数n唯一地表示成p_1^{a_1}\cdot \cdots \cdot p_r^{a_r}的形式,这里p_1<\cdots<p_r为不同素数,a_1,\cdots,a_r\in{Z^{+}},我们称这样的形式为n的标准(素数)分解式。

欧拉函数

对任意一个正整数n,在1n的这 个整数里,显然有些和n是互素的,而有些和n是不互素的,那些和n互素的整数 的数量就是n的欧拉函数,记作\phi(n)

那么\phi(n)该怎么计算呢?

我们都知道任意整数n都可以表示成它的所有素因子的乘积:

n=p_1^{l_1}p_2^{l_2}\cdots p_s^{l_s}\tag{1}

所以所有那些和n不互素的数,一定和n有其中某个素因子作为公共因子。所以我们只要从1n中的所有整数中,是p_1,p_2,\cdots,p_s的倍数的依次剔除,剩下的就是与n互素的数。

例如,p_1的倍数一共有多少个呢,由于p_1的倍数在1n中是均匀分布的,所以占据的比例是\frac{1}{p_1},剔除p_1的倍数后,还剩下n(1-\frac{1}{p_1})个;在剩下的数中,由于p_2的倍数在1n中也是均匀分布的,所以占据的比例是\frac{1}{p_1},所以再剔除 p_2的倍数后,剩下n(1-\frac{1}{p_1})(1-\frac{1}{p_2})个。以此类推,当把所有素因子的整数倍都剔除后,剩下的数共有n(1-\frac{1}{p_1})(1-\frac{1}{p_2})\cdots (1-\frac{1}{p_s})个。即:\phi(n) = n\prod_{i=1}^{s}(1-\frac{1}{p_s}) \tag{2}$

由此可见,求欧拉函数的关键在于求出n的所有素因子,即对n做素因子分解。

有一种特殊情况,n为素数,那么n 仅有一个素因子,即它自己。此时\phi(n)=n(1-\frac{1}{n})=n-1

还有一种特殊情况,n仅有两个素因子,即n=pq,那么\phi(n)=pq(1-\frac{1}{p})(1-\frac{1}{q})=(p-1)(q-1)。如果已知pq,显然\phi(n)是好求的;而如果仅知道n,而不知道pq,那么必须要先对n做素因子分解,得到pq,才能求得\phi(n)

如果这两个素因子p,q都极大,那么当然 n也就极大。要从1nn个数中找出这两个素因子,就如同大海捞针,复杂度极高。

丢番图方程

古希腊数学家丢番图首次系统地研究了方程的整数解问题,现在涉及整数解的方程都叫做丢番图方程,也叫不定方程。

丢番图方程,又称不定方程,是未知数只能使用整数的整数系数多项式等式;即形式如a_1x_1^{b_1} + a_2x_2^{b_2}+\cdots +a_nx_n^{b_n}=c的等式,并且其中所有的a_j,b_jc均是整数。若其中能找到一组整数解m_1,m_2\cdots m_n者则称之为有整数解。线性丢番图方程为线性整数系数多项式等式,即此多项式为次数为01的单项式的和。

【定理】设a_1,\cdots,a_n,b\in Z,则线性丢番图方程a_1x_1+a_2x_2+\cdots+a_nx_n=b有整数解当且仅当(a_1,\cdots,a_n)|b.

贝祖等式

对任何整數a,bm,关于未知数xy的线性丢番图方程(称为贝祖等式):ax+by=m.有整数解时当且仅当mab的最大公约数d的倍数,即(a,b)|m.