同余:数论中的重要概念。给定一个正整数m,如果两个整数a和b满足(a-b)能够整除m,即(a-b)/m得到一个整数,
那么就称整数a与b对模m同余,记作a≡b(mod m)。对模m同余是整数的一个等价关系。
数学上同余,两个整数除以同一个整数,若得相同余数,则二整数同余。
两个整数a、b,若它们除以整数m所得的余数相等,则称a与b对于模m同余或a同余于b模m
记作 a≡b (mod m)
读作 a同余于b模m,或读作a与b对模m同余。
例如 26≡2 (mod 12)
【定义】设m是大于1的正整数,a、b是整数,如果m|(a-b),则称a与b关于模m同余,记作a≡b(mod m),读作a与b对模m同余.
显然,有如下事实
(1)若a≡0(mod m),则m|a;
(2)a≡b(mod m)等价于a与b分别用m去除,余数相同。
【证明】
充分性: m|(a-b)——> a≡b(mod m)
设a=mq1+r1,b=mq2+r2
且0≤r1,r2<m
∵ m|(a-b)
又a-b=m(q1-q2)+(r1-r2).
∴必有常数n使得(r1-r2)=mn
则有m|(r1-r2).
∵0≤r1,r2<m,
∴0≤|r1-r2|<m
∴r1-r2=0
即r1=r2.
故a≡b(mod m).
必要性:a≡b(mod m)——>m|(a-b)
设a,b用m去除余数为r,
即a=mq1+r,b=mq2+r.
∵a-b=m(q1-q2)
∴m|(a-b).
同余的性质也比较多,主要有以下一些:
1.对于同一个除数,两个数之和(或差)与它们的余数之和(或差)同余。
2.对于同一个除数,两个数的乘积与它们余数的乘积同余。
3.对于同一个除数,如果有两个整数同余,那么它们的差就一定能被这个除数整除。
4.对于同一个除数,如果两个数同余,那么他们的乘方仍然同余。
同余的应用:
例题:求2001^2003除以13的余数
根据同余性质4,我们可以得出2001^2003≡12^2003(mod 13) (2001和12模13同余)
12^2003还是一个较大的数,很难求出它除以13的余数,这时,我们就要找出12的几次方与1对于模13是同余的。
根据试验,可得出12^2≡1(mod 13)
我们把12^2003拆成 (12^2)^1001×12^1,而 (12^2)^1001×12^1≡1×12≡12(mod 13)
这时,我们可以得出2001^2003除以13的余数为12,我们用计算器计算一下,这个答案是对的。
在数论中,线性同余方程是最基本的同余方程,“线性”表示方程的未知数次数是一次,即形如:
ax≡b (mod n)的方程。此方程有解当且仅当 b 能够被 a 与 n 的最大公约数整除(记作 gcd(a,n) | b)。
这时,如果 x0 是方程的一个解,那么所有的解可以表示为:
{ x0+kn/d | (k∈z) }
其中 d 是a 与 n 的最大公约数。在模 n 的完全剩余系 {0,1,…,n-1} 中,恰有 d 个解。
对于线性同余方程 ax ≡ b (mod n) (1)
若 d = gcd(a, n),d 整除 b ,那么b/d为整数。由裴蜀定理,存在整数对 (r,s) 可用辗转相除法使得 ar+sn=d,
因此 x0=rb/d是方程 (1) 的一个解。其他的解都关于n/d与 x 同余。即x≡x0+(n/d)*t (mod n) (0≤t≤d-1)。
举例来说,方程12x ≡ 20 (mod 28)中 d = gcd(12,28) = 4 。
注意到 4 = 12 (-2)+281,因此 x0≡5*(-2) ≡-10 ≡4(mod 7)是一个解。
对模 28 来说,t=1,x≡4+(28/4)*1≡11 (mod 28);
t=2,x≡4+(28/4)*2≡18 (mod 28); t=3,x≡4+(28/4)*3≡25 (mod 28) 。
所有的解就是 {4,11,18,25} 。
求关于 x 的同余方程 ax ≡ 1 (mod b)的最小正整数解。
即求ax=mb+r 1=nb+r
变形ax+(n-m)b=1,此方程即拓展欧几里德的应用ax+by=gcd(a,b),(n-m相当于y)
事实上ax ≡1(mod b) 有解的必要条件是gcd(a,b)|1,即gcd(a,b)=1;
使用拓展欧几里得可知 ax+by=1(x,y是整数)
扩展欧几里得定理
扩展欧几里得定理:对于两个不全为0的整数a、b,必存在一组解x,y,使得ax+by==gcd(a,b);
拓展欧几里得实现,下面的程序中,x和y用全局变量保存
int gcd(int a,int b)
{
int t,d;
if(b==0)
{
x=1;
y=0;
//此时b==0,也就是说gcd(a,0)==a。原式变为ax+by==a=gcd(a,b)--> x==1,y==0
return a; //返回a,b最大公约数的值
}
d=gcd(b,a%b); //欧几里得求最大公约数应用
t=x;
x=y;
y=t-(a/b)*y; //不明处2
return d; //返回a,b最大公约数的值
}
//不明处2 解释 ax+by==gcd(a,b)(1)
说明规则,x,y表示第一次递归时的值,x1,y1表示第二次递归时的值。
那么gcd(a,b)==gcd(b,a%b),同时都代入式1,
有ax+by==bx1+(a%b)y1。将右边变形一下
bx1+(a%b)y1==bx1+(a-(a/b)b)y1==ay1+b(x1-(a/b)y1),
最终得到ax+by==ay1+b(x1-(a/b)*y1)
也就是说:
上一深度的x等于下一深度的y1,
上一深度的y等于下一深度的x1-(a/b)*y1。
*需要注意,上面推导时用的除法都是整型除法
因此,得到了不定式ax+by==gcd(a,b)的一组解,x、y。
那么对于一般的不定式ax+by==c,它的解应该是什么呢。
很简单,x1=x(c/gcd(a,b)),y1=y(c/gcd(a,b))
再深入一点,就解出这么一组解其实一般来说是解决不了什么问题的,
我们现在要得到所有的解,那么这所有的解究竟是什么呢?
假设d=gcd(a,b). 那么x=x0+b/dt; y=y0-a/dt;其中t为任意常整数。
代码如下:
#include<stdio.h> int Extragcd(int a,int b,int *x,int *y) { int d,t; if(b==0) //递归调用终止条件,当根据欧几里得辗转相除法则,余数为0停止 { *x=1; *y=0; return a; } else { d=Extragcd(b,a%b,x,y); t=*x; //根据下一个x1,y1的值,倒推前一个x,y的值 *x=*y; *y=t-a/b*(*y); return d; } } int main() { int a,b,x,y; int ans; scanf("%d%d",&a,&b); ans=Extragcd(a,b,&x,&y); //同余方程 ax ≡1 (mod b) 有解的充分条件是 gcd(a,b)==1 if(ans!=1) return 0; //根据若x是方程的一个解,则方程的所有解为x+k*b k为整数 x=x%b; //保证最小的正整数解x ,且x属于{0,1,2,3...b-1} while(x<=0) x+=b ; printf("%d\n",x); return 0; }