同余&逆元&不定方程
这篇文章主要介绍同余&逆元&不定方程及代码实现
由于本人比较菜,所以一些定理不予证明
同余的概念
同余定理是数论中的重要概念。给定一个正整数m,如果两个整数a和b满足(a-b)能够被m整除,即(a-b)/m得到一个整数,那么就称整数a与b对模m同余,记作a≡b(mod m)
【定义】设m是大于1的正整数,a、b是整数,如果m|(a-b),则称a与b关于模m同余,记作a≡b(mod m)。显然易得如下:
1.若a≡0(mod m),则m|a;
2.a≡b(mod m)等价于a与b分别用m去除,余数相同。
充要性证明
充分性:
若a和b用m相除留下相同的余数r,则 a=q1m+r, b=q2m+r,q1和q2为某两个整数,由此的a-b=(q1m+r)-(q2m-r)=m(q1-q2),根据整除定义,我们有m|(a-b),由同余式定义得出结论:a≡b(mod m)
必要性:
若a和b用m相除留下相同的余数r,则 a=q1m+r,b=q2m+r,所以a-b=m(q1-q2) 故 m|(a-b)。
同余性质
反身性:a≡a (mod m)
对称性: 若a≡b(mod m),则b≡a(mod m)
传递性: 若a≡b(mod m),b≡c(mod m),则a≡c(mod m)
同余式相加:若a≡b(mod m),b≡c(mod m),则a ± c≡b ± d(mod m)
同余式相乘:若a≡b(mod m),b≡c(mod m),则ac≡bd(mod m)
线性运算:如果a≡b(mod m),c≡d(mod m),那么a ± c≡b ± d(mod m),且a * c≡b * d(mod m)
除法:若ac ≡ bc (mod m) c≠0 则 a≡ b (mod m/gcd(c,m)) 其中gcd(c,m)表示c,m的最大公约数。特殊地 ,gcd(c,m)=1 则a ≡ b (mod m)
幂运算:如果a ≡ b (mod m),那么a^n ≡ b^n (mod m)
若a ≡ b (mod m),n|m,则 a ≡ b (mod n)
若a ≡ b (mod mi) (i=1,2…n) 则 a ≡ b (mod [m1,m2,…mn]) 其中[m1,m2,…mn]表示m1,m2,…mn的最小公倍数
逆元&不定方程
逆元
每个数a均有唯一的与之对应的乘法逆元x,使得ax≡1(mod b) , 一个数有逆元的充分必要条件是gcd(a,b)=1,此时逆元唯一存在 。
【含义】模b意义下,1个数a如果有逆元x,那么除以a相当于乘以x。
【定义】正整数 a, b,如果有 ax ≡ 1(mod b),则称 x 的最小正整数解为 a 模 b的逆元
不定方程
【定义】形如ax+by=c(a,b,c均为常数,且a,b均不为0),一般情况下,每一个x的值都有一个y值和它相对应,有无穷多组解。如果方程(组)中,解的数值不能唯一确定,这样的方程(组)称为不定方程
不定方程有整数解的条件
整系数二元不定方程ax+by=c中的系数a,b的最大公约数能整除c。
反之,如果if(c%gcd(a,b)) 则 无解
逆元&不定方程解法
扩展欧几里得算法求不定方程
- 引:裴蜀定理
- 设a, b是不全为零的整数,则存在整数x, y 使得 ax + by = gcd(a, b)
我们都知道,欧几里得公式可以由这个式子表达
gcd(a, b) = gcd(b, a % b)
通过这个式子,我们可以不断递推到b = 0, 此时a即为a和b的最大公约数
将式子展开得到如下
1.gcd(a, b) = a * x1 + b * x1
2.gcd(b, a % b) = b * x2 + (a % b) * y2
由欧几里得公式可得到
a * x1+b * x1=b * x2 + (a % b) * y2
其中 a % b = a - (a / b) * b
得 a * x1 + b * y1 = b * x2 + [a - (a / b) * b]y2
化简得 a * x1 + b * y1 = a * y2 + b * [x2 - (a / b) * y2]
由待定系数法得:
1.x1 = y2
2.y1 = x2 - (a / b) * y2
以上即扩展欧几里得算法
也就是说有了gcd(b, a % b)的解x2, y2就可以推出gcd(a, b)的解x1, y1
我们可以用类似求gcd的方法求解,一直推到x=1,y=0(递归边界),然后回溯即可求出特解
通过特解求出最小整数解&通解
设特解分别为x0,y0
则最小解为:
x0=x0%(b/gcd(a,b))
则通解为:
x=x0+k*b/gcd(a,b)
y=y0-k*a/gcd(a,b)
又因为方程建立在gcd基础上,方程左边为gcd而非c,所以答案需在上面的基础上乘上
c/gcd(a,b)
所以最小解为
x0=(x0*c/gcd(a,b))%(b/gcd)
易知逆元为特殊的不定方程,ax≡1(mod b) 等价于ax-by=1
所以同样可以用扩展欧几里得算法求解
代码实现
扩展欧几里得算法的三大应用
求不定方程ax+by=c的最小正整数解
void exgcd(int a,int b,int &x,int &y){
if(b==0){
x=1,y=0;
return ;
}
exgcd(b,a%b,y,x);
y-=(a/b)*x;
}//x即为特解;
int mod=b/(gcd(a,b));
ans=(x*(c/gcd(a,b))%mod+mod)%mod;
//小技巧,+mod后%mod可以防止出现负解;
求方程ax≡1(mod b) 的最小正整数解(a的逆元)
void exgcd(int a,int b,int &x,int &y){
if(b==0){
x=1,y=0;
return ;
}
exgcd(b,a%b,y,x);
y-=(a/b)*x;
}//x即为特解;
//已知gcd(a,b)=1,则mod=b/gcd(a,b)=b;
//同理,c/gcd(a,b)=1/1=1;
ans=(x%b+b)%b//求出最小整数解&防止出现负解;
求模线性方程ax≡b (mod n)
对于模线性方程ax≡b (mod n)可以化简为ax+ny=b设d=gcd(a,n)
则当且仅当b%d==0时方程有解,且有d个解
等式两边同时乘以b/d,则方程变为axb/d+nyb/d=b
设ax+ny=d特解为x‘,y’
则原方程解为x=x‘ * b/d,y=y’ * b/d
故ax≡b (mod n)特解为x0=x' * (b/d)%n
d个解为xi=x0+i*(n/d)%n (i=0,1,...,n-1)
解的间隔为n/d
void exgcd(int a,int b,int &gcd,int &x,int &y){
if(b==0){
x=1,y=0;
gcd=a;
return ;
}
exgcd(b,a%b,y,x);
y-=(a/b)*x;
}
bool check_find(int a,int b,int n){
int x,y,x0,gcd;
exgcd(a,b,gcd,x,y);
int d=gcd;
if(b%d) return false;
x0=x*(b/d)%n;//特解
for(int i=0,i<d;i++) printf("%d\n",x0+i*(n/d));
return true;
}