逆元
广义的来讲,对于任何域中的元素,有乘法运算和单位元I,如果对于该域中的元素A,存在另一个元素A′,且满足A×A′=I,那么A′就是A的逆元。
这里我们只讨论在整数域里的逆元,也就是当A∈Z且I=1,其实这里的逆元A′=A1,但是我们要在模的意义下讨论它的求法。
在取模意义下,我们只需求出一个数inv,是的这个数与A1同余即可,那么这个数inv就是A在取模意义下的逆元。
费马小定理
内容:对于x,在模p,p∈P质数的意义下,有xp−1≡1(mod p)
我们变换一个形式,左右同时除以x,就是xp−2≡x1(mod p),那么我们就发现xp−2和x1是同余的,那么xp−2就是x的逆元了。
费马小定理证明:
- 用欧拉定理直接证明,这个就后面再说。
- 我们用剩余系来看:
引理1:假设a为1∼p−1内的一个数,那么a,2a,3a,⋯,(p−1)a可以在模p的意义下不重复的取遍1∼p−1的值。引理1的证明-这里面有
那么我们将a,2a,⋯,(p−1)a乘起来,在模p的意义下也就相当于把1,2,⋯,(p−1)乘起来,那么可以得到ap−1(p−1)!≡(p−1)!(mod p),然后两端同时除以(p−1)!就可以得到ap−1≡1(mod p)了,于是得证。
所以用费马小定理求取逆元的代码如下:
int inv(int a,int b=p-2){
int ans=1;
for(;b;b>>=1,a=(a*a)%p)if(b&1)ans=(ans*a)%p;
return ans%p;
}
欧拉定理
内容:对于x,在模p(p为任意与x互质的数)意义下,有xφ(p)≡1(mod p),其中φ(p)为欧拉函数,表示1∼p−1中与p互质的个数。
那么我们知道,当p为质数时就有φ(p)=p−1,那么这个就是费马小定理了。
我们同样进行变形,可以得到xφ(p)−1≡x1(mod p),那么这里xφ(p)−1就为x的逆元了。
我们看,这里只要求x,p互质,并没有要求p为质数,所以欧拉定理求逆元比费马小定理求逆元应用更加广泛。
其他应用:当快速幂取模时,指数较大,但我们发现xφ(p)≡1(mod p),所以我们可以将指数模了φ(p),相当于除以很多个1,然后再来快速幂。
欧拉定理的证明:
我们先令x1∼xφ(p)为p的简化剩余系,再令pi=xxi,其中gcd(xi,p)=1
引理1. pi之间两两在模p的意义下不同余,同样xi也是。
假设有pi≡pj(mod p),那么pi−pj≡0(mod p),我们将其变形得xxi−xxj≡0(mod p),也就是x(xi−xj)≡0(mod p),由于gcd(x,p)=1,所以只有在xi−xj为p的倍数时,这个式子才满足,而xi,xj≤p,那么它们相减就更加不可能为p的倍数了,所以假设不成立,得证。
引理2. 每个pi模p的结果都与p互质。
假设pi≡r(mod p),gcd(p,r)>1
那么变形就有xxi=kp+r,也就是xxi−kp=r,我们可以得知xxi肯定与p互质(因为x,xi分别与p互质),那么我们令d=gcd(p,r),那么变形可知xxi=r+kp,也就是xxi=d(w1+kw2)其中(dw1=r,dw2=p),那么xxi肯定有因子d,那么它与p就不互质了,所以假设不成立,得证。
由1,2引理可得,(xx1×xx2⋯×xxφ(p))≡(x1×x2⋯×xφ(p))(mod p)
所以变形得xφ(p)∏xi≡∏xi(mod p),两端同除就得xφ(p)≡1(mod p)
扩展欧拉定理
内容:
xk=⎩⎨⎧xkmodφ(p)xkxkmodφ(p)+φ(p)gcd(x,p)=1k<φ(p)gcd(x,p)̸=1,k≥φ(p)
扩展欧几里得算法
内容 : exgcd(a,b,x,y) 【见详解于这里】
这个也就是求方程ax+by=c的解。
那么我们将ax≡1(mod y)看作方程ax+by=1,那么当gcd(a,b)=1的时候,这个肯定有解,所以我们用扩展欧几里得定理求出x,那么可以发现ax≡1(mod y)的,所以此时的x就是在mod y意义下的逆元。
线性递推求法
首先我们知道1的逆元一定为1,所以考虑i的逆元(i>1)。
对于模数为p,我们令p=i×k+d(d<i),那么对于k,d则有:k=⌊ip⌋,d=p mod i
那么原式可以写成i×k+d≡0(mod p)
两边同时乘以i−1×d−1可得
d−1×k+ii−1≡0(mod p)
那么i−1≡(−k×d−1)(mod p),所以将k,d带回即有:
i−1≡−⌊ip⌋×(p mod i)−1(mod p)
由于i以内的逆元已经求出,所以递推即可。
所以inv(i)=(−ip)×inv(p mod i)
参考大佬文章IN-Luogu