涉及内容:欧几里得,扩展欧几里得,欧拉函数,费马小定理,欧拉定理,逆元,中国剩余定理
符号声明
∑ 表示求和符号。
∏ 表示求积符号。
a≡b(modn) ,表示整数a,b对模n同余。
a|b 表示a整除b。
x−1(modn) 表示x 对模n的数论倒数。
max{a,b}表示a,b中较大的数。
min{a,b}表示a,b中较小的数。
gcd(a,b)表示a,b的最大公约数。
lcm(a,b)表示a,b的最小公倍数。
[x]表示不超过x的最大整数。
概念
唯一分解定理(Fundamental Theorem of Arithmetic):对于一个合数n,仅能以一种写成n= x1e1∗x2e2......xnen .
剩余系: 若 x1,x2......xn 对模n两两不同余,则 x1,x2......xn 构成模n的一个完系。
大家都知道欧几里得(Euclid)算法,这也许是在数论中最广为人知的定理。我们来重新温习一下。这个算法基于一个定理gcd(a,b)=gcd(b, a mod b),下面我们给出这条定理的证明。
证明:
因为a可表示为a=bk+r的形式
0≤r<b
设d|a,d|b,
因为r=a-kb,所以d|r,所以d|gcd(b,a mod b)
又假设d|(b,a mod b)
因为d|b,d|r,又因为a=bk+r,所以d|r,所以d|(a,b)
所以gcd(a,b)和gcd(b, a mod b)的公约数一样,所以其最大公约数也一样,得证。
当然求最大公约数,还有其他办法。比如说更相减损术。我们的老祖宗有这样一个办法,在《九章算术》一书中有这样一句话:可半者半之,不可半者,副置分母、子之数,以少减多,更相减损,求其等也。以等数约之。
但是一般情况我们用前者求最大公约数,为什么呢?因为前者的时间复杂度稳定于O( logn ),而后者则有可能退化为O(n).下面我们来分析一下时间复杂度
欧几里得时间复杂度分析:
根据前面的定理:gcd(a,b)=gcd(b,a mod b)。
我们分类讨论一下:
①当a ≥2×b 时,两者至少数字大小至少减少一半。
②当a <2×b 时, a(modb) <a÷2 。
时间复杂度为O( logn )。
还有一个与欧几里得算法时间复杂度相关的定理。
定理:设f[n]表示斐波那契数列的第n项(f[0]=0,f[1]=1,f[n]=f[n-1]+f[n-2], n≥2 ), a>b≥1 ,且euclid函数调用了n次,则 a≥f[n+2],b≥f[n+1] 。
证明:利用数学归纳法,没有人不会吧。
①当k=1时, a≥f[3],b≥f[2] ,成立。
②假设当n=k时成立, a≥f[n+2],b≥f[n+1] 。
当n=k+1时,从gcd(a,b) ⇒ gcd(b, a mod b),调用了一次递归,然后从gcd(b, a mod b)开始调用了k次。
所以 b≥f[k+2],a(modb)≥f[k+1] 。
因为 a>b ,
所以 a≥b+a(modb)≥f[k+2]+f[k+1]=f[k+3] ,
所以当n=k+1时同样满足条件。
③所以对于任意正整数,定理均成立。
补充说明:关于费波那契数列还有很多有趣的性质,可以自己上网找一找。这里不再赘述。
接下来就该讲一下扩展欧几里得,首先介绍一下裴蜀定理(Bézout’s identity)裴蜀定理:对于任意整数a,b关于未知数x,y的线性丢番图方程:ax+by=c,方程有解当且仅当gcd(a,b)|c,且有解时必有无穷多个解。
证明
首先证明充要性:设d=gcd(a,b),如果有整数解则c是d的倍数,又设a=dp,b=dq,则此时gcd(p,q)=1,那么c=ax+by=d(p+q),显然d|c。充分性得证。
然后我们证明必要性:如果c是d的倍数,则方程ax+by=c有整数解。在使用欧几里得计算gcd(a,b)时,最后调用的是gcd(d,0),所以对于(p,0)存在dx+0y=c,(只需让x=c/d)。欧几里得的算法精髓就是gcd(a,b) ⇒ gcd(b,a mod b),假设存在bp+(a mod b)q=c,那么
ax+by
=bp+(a mod b)q
=bp+(a-[a/b]*b)q=aq+b(p-[a/b]q)。
即ax+by=aq+b(p-[a/b]q),根据恒等式定理,对比两边系数得x=q,y=p-[a/b]q。必要性得证。
补充说明:在这里用了一个结论:a mod b=a-[a/b]*b。证明比较简单这里也不赘述。
扩展欧几里得就是用来做这样一件事。已知a,b,求x,y使得ax+by=gcd(a,b),有人可能会问,一定存在这样的x,y。根据贝祖定理,一定存在这样的x,y,贝祖定理(Bezouts identity):对于整数a,b存在整数x,y使得ax+by=c。证明如下:
不妨设ab≠0,(若其中有一个为0结论显然成立)且|a|≤|b|
设b=aq1+r1,(0≤r1<|a|),q1,r1∈Z,若r1=0,则辗转相除法到此为止,否则用a来除以r1得到a=r1q2+r2 ( 0≤r2<r1 ),依次讨论,转转不已,由于r1>r2>r3>r4….,所以到某一步时,rk+1=0,于是我们得到下列式子:
b=aq1+r1(0≤r1<|a|)
a=r1q2+r2(0≤r2<r1)
r1=r2q3+r3(0≤r3<r2)
转转不已
rk−2=rk−1qk+rk
rk−1=rkqk+1
因为d=gcd(a,b)
所以d|r1,d|r2……d|rk−1,d|rk
而从第k+1个式子倒推又得
rk|rk−1,rk|rk−2……rk|a,rk|b
因为rk是(a,b)的公因数,所以r_k≤d,又因为d|rk,所以d=rk
利用d=rk及第k个式子得
d=rk−2−rk−1qk
又由第k-1个式子得
rk−1=rk−3−rk−2qk−1
带入上式可知d可以表示为rk−2和rk−3的线性组合,依次倒推,可知 d可表示为a,b的线性组合。即存在x,y使得ax+by=d。证毕。
Pascal:
function exgcd(a,b,x,y:longint):longint;
var
t,r:longint;
begin
if b=0 then
begin
x:=1;
y:=0;
exit(a);
end;
r:=exgcd(b,a mod b x,y);
t:=x;
x:=y;
t:=t-a/b*y;
exit(r);
end;
C++:
int exGcd(int a, int b, int &x, int &y)
{
if(b == 0)
{
x = 1;
y = 0;
return a;
}
int r = exGcd(b, a % b, x, y);
int t = x;
x = y;
y = t - a / b * y;
return r;
}
这里给出拓展欧几里得的C++和pascal代码。相信读者一定发现这个代码比原来的普通的欧几里得算法多了几条赋值语句。我们来简单理解一下。
设p=x,q=a mod b,我们求出(x,y)使得px+qy=gcd(p,q)。
由px+qy=gcd(p,q),从而推出
bx+(a-a/b*b)y=gcd(p,q),有前面的①
又推出bx+(a-a/b*b)y=gcd(p,q)=gcd(a,b),整理得
ay+b(x-a/b*y)=gcd(a,b);对于a,b来说对应的应该是y和(x-a/b*y)。
接着就来思考一下求解x,y的方法。
①当b=0 时,gcd(a,b)=a,此时x=1,y=2
②当ab≠0 时
设ax+by=gcd(a,b)则
bx2+(amodb)y2=gcd(b,amodb)由定理gcd(a,b)=gcd(b,amodb)可得
ax+by=bx2+(amodb)y2
整理得:
ax+by=bx2+(a−(a/b)∗b)y2=ay2+bx2−(a/b)∗by2;(是不是有点眼熟?)
即ax+by=ay2+b(x2−a/b∗y2)
根据恒等式定理,分别对比两边a,b的系数得
x1=y2,y1=b(x2−a/b∗y2)
这样我们就得到了求解 x,y 的方法: x1,y1的值基于x2,y2。 以上方法是递归定义的,所以总有一个出口,所以递归no problem。
古代名将岳飞说过‘’阵而后战,兵法之常,运用之妙,存乎一心‘’算法竞赛也是如此。学习了拓展欧几里得之后就让我们来做点题吧。
问题一:求直线上ax+by+c=0上有多少个点(x,y),满足 x∈[x1,x2],y∈[y1,y2] 。
有了扩展欧几里得,这就是道水题,移项。ax+by=-c,直接求解即可。不会求解?举个例子,比如7x+8y=30,首先调用扩展欧几里得求出一组特解即7*(-1)+8=1,两边同时乘30/1,得-210+240=30,其他情况类比。
希望读者能够熟练掌握这个扩展欧几里得算法,因为在之后我们还要反复用到这个扩展欧几里得。
下面我们就来介绍一下:数论四大定理。
首先介绍一下费马小定理(Fermat’s little theorem),它在处理整数的方幂问题中起着重要的作用,是初等数论中的一个重要定理。
费马小定理:设p质数,且gcd(a,p)=1,则 ap−1≡1(modp)
证明:
首先我们知道这样一个事实,1,2,……p-1,模p互不同余,考虑这样一个数列a,2*a,…..,(p-1)a,设 x,y∈{1,2,....p−1} ,且 x≠y ,若 ax≡ay(modp) 因为gcd(a,p)=1,同余式两边可约去a,得 x≡y(modp) 与假设矛盾。所以我们考虑的这个数列模p互不同余,所以ax用p除,余数为1,2,….p-1中的一个,这就构成了一个模p的完全系。
由前面的证明知道当x取遍1,2,….p-1时,它模p的余数也取遍了1,2,….p-1,所以 a∗(2∗a)∗...(p−1)a≡1∗2∗......(p−1)(modp) ,即 (p−1)!∗ap−1≡(p−1)!(modp) ,又因为p是个质数,所以gcd((p-1)!,p)=1,所以同余式两边可同时约去(p-1)!,即 ap−1≡1(modp) ,得证。
补充说明:有一点需要注意的是,费马小定理的逆定理是不成立的,比如一个经典的例子, 2340≡1(mod341) ,但341不是质数,341=11*31。
101010≡106k+4≡104≡34≡4(mod7) 。
费马小定理的确是一个十分有用的定理,在后面学习米勒 -拉宾素性测试的时候还要用到它,希望读者能记住这个定理即使不会推也没有关系,毕竟最主要的还是应用。
接下来便要讲一下著名的欧拉函数(Euler’s totient function)及欧拉定理(Euler Theorem),首先讲一下欧拉函数,欧拉函数记为 φ ,表示的是对于一个正整数n,1到n当中与n互质的数的个数。
关于欧拉函数有一些常见的性质:
①欧拉函数是积性函数。(什么叫积性函数?考虑对于一个定义域为正整数定义域的函数f,若任意两个互质的数都满足f(ab)=f(a)*f(b),则函数f被成为积性函数,补充:若ab不一定互质,则f为完全积性函数。)
② ∑d|nφ(d)=n
③ φ(pk)=(p−1)pk−1 ,其中 p为质数
④ 设n>1,1到n中与当中与n互素的数的和为nφ(n)2
⑤对于一个素数p它的欧拉函数的值,即为p-1。
欧拉函数有一个计算公式:设
n=p1e1∗p2e2......pkek ,那么 φ(n)=n∗∏ki=1(1−1/pi) 。由于推导欧拉函数的过程较为繁琐,这里略去
⑥一到n当中和为n且互质的无序数对共有 φ(n) /2对。
证明:
首先我们很显然的知道设一个数a与n互质,那么n-a也与n互质,证明显然,我们也有gcd(n,a)=gcd(a,n mod a)=gcd(a,n-a)=1.,得证。
值得一提的是,对于求1到n中的欧拉函数的值,可以用类似线筛的方法求出,下面该出代码,由于比较简单,这里仅仅只给出代码:
var
bz:array[0..10000000] of boolean;
fa,p:array[0..10000000] of int64;
tot,i,j,k,n,m,n1:longint;
sum:int64;
begin
readln(n);
for i:=2 to n do
begin
if not bz[i] then
begin
inc(tot);
p[tot]:=i;
fa[i]:=i-1;
end;
for j:=1 to tot do
begin
if i*p[j]>n then break;
bz[i*p[j]]:=true;
if i mod p[j]=0 then
begin
fa[i*p[j]]:=fa[i]*p[j];
break;
end
else
fa[i*p[j]]:=fa[i]*(p[j]-1);
end;
end;
fa[1]:=1;
end.
欧拉定理: aφ(n)≡1(modn) ,这要求a与n互质,是不是突然发现其实费马小定理就是欧拉定理的一个特例呢?它的证明也是比较简单的。
证明:将1到n中与n互素的依次记为
逆元其实就有点与实数中倒数的概念相似,对于任意的n>1,如果gcd(a,n)=1,则方程 ax≡b(modn) 有唯一解,如果b=1,那么要求的x是a对模n的乘法逆元,补充如果 gcd(a,n)>1 ,那么可能无解也可能解不唯一,一般来说,我们求逆元有三种办法,
方法1:费马小定理,假设此时p为质数,且a与p互质,我们要求a模p的逆元,那么此时十分显然, ap−2,即是所求,
方法二:利用欧拉定理,假设此时,p不为质数,怎么办?考虑欧拉定理,我们要求a模p的逆元,只需求 aφ(p)−1,即可,
方法三,利用扩展欧几里得,首先将原式进行转化,变为ax+ny=b,然后用之前介绍过的方法进行简单判断是否有解,继而求出ax+ny=b的一组特解,方程的一般解为 (x0+k∗[n/p],y0+k∗[a/p])
举个例子,比如要求9/7 ≡?(mod5) ,显然7模5的逆元就是7^(5-2),那原式就等价于求 9∗75−2≡?(mod5) 。
威尔逊定理给出了判断一个自然数是不是素数的充分必要条件,当且仅当p为质数时, (p−1)!≡−1(modp) ,听说这个东西与mr素性测试有关,就简单提一提。我们仅仅只给出证明。
①首先证明充分性:反证法,假设p不为质数,那么p的素因子,一定都在1到p-1中,那么 (p−1)!≡0(modp) ,与假设矛盾。
②其次我们证明必要性:
考虑 ∀i∈{1,2...p−1},∃j∈{1,2...p−1} ,使得 ij≡1(modp) ,我们将式子进行变形,变成 ij+py=1 那么该方程组的一般解为(考虑关于i,p的方程) (j0+pk,y0−ik) ,其中 j0,y0 是一组特解,不懂为什么的,可以上网搜一搜(二元一次不定方程),这里不再赘述,然后对于这个特解,我们只需让 j=((j0(modp)+p))(modp) ,(解释一下为什么要这样,因为我们得到的 j0 ,有可能是一个负数,然后我们模p之后,就能保证 j0 的绝对值小于p,然后再加上一个p此时必定是正数,因为考虑到有可能本身就是一个正数,还要模上一个p),然后我们继续考虑,这个j有没有可能等于i呢?当然有可能,设 i2≡1(modp) 变形得 i2−1≡0(modp) ,利用平方差公式将右边变成 (i+1)(i−1)≡0(modp) ,此时当i=1或i=p-1时模p为0。然后我们就得到了这样一个结论,2到p-2当中这些数两两配对(配对是指乘起来模p等于1)。
那么考虑原式 (p−1)!(modp) 等于(p-1),(因为2到p-2当中每个数都有一个相应的且不相等的数使得这两个数相乘模p之后为1,比如说p=7时,2和4配对,8模7等于1,3和5配对,15模7等于1, 6!≡1× ( 2×4 ) ×(3×5) ×6 ≡6(modp) )所以,得证。
定理内容
对于这样一个线性的同余方程组
毕竟这是我第一次写博客,同时碍于我的水平有限,难免会有写错的,希望大家批评指正,谢谢。