本期我们要复习的目录:
- 裴蜀定理
- 扩展欧几里得算法
- 逆元
- 费马小定理
- 欧拉定理
- ......
裴蜀定理
对于ax+by=k这个丢番图方程,如果要x,y为整数,则需满足k为gcd(a,b)的倍数。
扩展欧几里得算法
根据裴蜀定理:$ax+by=gcd(a,b)$是有整数解的。
而我们知道:$bx+(a%b)y=gcd(a,b)$也是有整数解的。
于是乎:我们可得:
$$ax_1+by_1=bx_2+(a%b)y_2=gcd(a,b)$$
然后呢,我们知道:$$a%b=a-\lfloor{\frac{a}{b}}\rfloor ×b$$
所以呢,可得:
$$ax_1+by_1=bx_2+ay_2-b×\lfloor{\frac{a}{b}}\rfloor y_2$$
而$\lfloor{\frac{a}{b}}\rfloor$在C++中就是$\frac{a}{b}$
根据待定系数法,$x_1=y_2$,$y_1=x_2-\lfloor{\frac{a}{b}}\rfloor y_2$
据此,我们只需要用一个递归函数,不停更新$x_1$和$y_1$的值,就可以得出$x$和$y$的一个整数解了。这就是扩展欧几里得算法。
附上函数:
#include<bits/stdc++.h>
using namespace std;
int Extended_Euclidean_algorithm(long long a,long long b,long long &x,long long &y)
{
if(b==0) {x=1;y=0;return a;}
else
{
long long x1,y1;
Extended_Euclidean_algorithm(b,a%b,x1,y1);
x=y1;
y=x1-a/b*y1;
}
}
int main()
{
long long x,y,a,b;
cin>>a>>b;
Extended_Euclidean_algorithm(a,b,x,y);
cout<<x<<" "<<y;
return 0;
}
$\color{Crimson}\text{乘法逆元}$
一、定义:
如果有$ab≡1(mod p)$,则称$b$是$mod p$意义下$a$的乘法逆元。记$b=inv(a)$ 或 $b=a^{-1}$(定义了剩余系中的除法)
二、求逆元的方法
(已知量:a与p,求x)
1.扩展欧几里得算法
$ax≡1(mod$ $p)$可转化为:$ax-py≡1(mod$ $p)$。
然后套用exgcd解方程,并检查gcd(a,p)是否为1。
如果为1,则将x调整到$1$~$p-1$即可。
时间复杂度:$O(log$ $n)$
2.费马小定理
在$p$为素数时,满足:
$a^{p-1}≡1(mod$ $p)$。
可得:$a×a^{p-2}≡1(mod$ $p)$。
即$a^{p-2}$是$a$在模$p$意义下的逆元。
对于$a^{p-2}$只需用快速幂即可得出结果。
时间复杂度:$O(log$ $n)$
3.递推
$O(n)$的时间可以处理出$1$~$n$在$mod~p$ 意义下的逆元
证明:
已知$1^{-1}≡1(mod~p)$
则我们设$p=k×i+r(r<i,1<i<p)$
再将这个式子放到$mod~p$意义下可得
$$k×i+r≡0~~~~~~~~~~~~~~~~~~~(mod~p)$$~~~~~~~~~~
两边同乘$i^{-1}×r^{-1}$即可得到:$$k×r^{-1}+i^{-1}≡0(mod~p)$$~~~~~~~~~~~~~~~(mod~p)$$
移项得:$$i^{-1}≡-k×r^{-1}
得:$$i^{-1}≡-\lfloor{\frac{p}{i}}\rfloor×(p~mod~i)^{-1}(mod~p)$$
由此,得到递推求逆元式:
inv[i]=(mod-mod/i)×inv[mod%i]%mod$$
引用资料:
【数论】乘法逆元总结