乘法逆元
目录
1.扩展欧几里得算法
1.1算法内容
1.2解不定方程ax+by=c
1.3解同余方程ax≡c(mod b)
1.4逆元求解
2.模板题
T1.luoguP3811
T2.luoguP5431
3.小结
正文
1.1算法内容
欧几里得算法所求的是两个数的最大公约数,复杂度是log级别的,他的关键是把求gcd(a,b)转化为求gcd(b,a%b);
扩展欧几里得算法则主要解决“解不定方程ax+by=gcd(a,b)”这一问题,是在欧几里得算法的基础上进行的
首先,我们来看欧几里得算法的递归边界,这时,b=0,a=gcd(a,b),显然有x=1,y=0这组解使a=gcd(a,b),b=0时方程成立
我们令此时的a,b,x,y为a1,b1,x1,y1,尝试用这组解递推另一组解
下面是推导过程

程序如下:
int exGcd(int a,int b){ if(b==0){ x=1; y=0; return a; } int g=exGcd(b,a%b); int tmp=x; x=y; y=tmp-a/b*y; return g; }
上面求出的是方程的一组特解,要求出通解,则需调整常数
注意到ab=(a,b)*[a,b]
所以可以在x后加上b/gcd(a,b),y后减去a/gcd(a,b),易得所得仍是方程的解
通解为:
可以利用这种方式求在一定范围内的解
比如求方程在[0,m)范围内的解,则只需x=(x%m+m)%m;
因为exGcd函数可能求出的是负解,所以要加上m
1.2解不定方程ax+by=c;
根据扩展欧几里得定理,方程ax+by=gcd(a,b)的解我们会求了,那如何利用到解这个方程中呢?
若c%gcd(a,b)==0,那么可以先解方程ax+by=gcd(a,b),再把所有解乘上c/gcd(a,b);
事实上这样得到的只是方程的部分解
思考一下,我们在解方程ax+by=gcd(a,b)时在特解后所加的常数会相互抵消,所以将这两个常数扩大整数倍是无意义的
所以方程的解应扩展为

到这里,c%gcd(a,b)==0的情况就考虑完了,那么c%gcd(a,b)!=0的情况呢?
若c%gcd(a,b)!=0
我们对等式两边同时对gcd(a,b)取模,而左边等于0,右边不等于零,两个相等的整数,模同一个数的余数肯定相等,所以矛盾,该方程无整数解
所以方程ax+by=c有整数解的充要条件是c%gcd(a,b)=0;
1.3解同余方程ax≡c(mod b)
这个方程等价于解方程ax=by+c
令y=-y,得到ax+by=c;
解法见1.2
1.4乘法逆元
终于到了求逆元的时候了
什么是逆元呢?
我们在小学时就学过,除以一个数等于乘这个数的倒数
逆元就是一个数在模p意义下的倒数
举个例子,如果b是a在模p意义下的逆元,那么就有ab≡1(mod p)
那么逆元有什么用呢?
如果一个很大的数a,去除以一个数b,然后商对p取模
因为除法不可以先取模再相除,而懒惰的我又不想写高精
逆元就上场了
他可以将除法转化为乘法,问题就简化了很多
说了这么多,逆元怎么求呢
注意这个关系ab≡1(mod p)
这不就是我们上面讨论了好久的方程吗,所以解法就见上吧
1.1 1.2 1.3
由上面的结论知,一个数在mod p意义下存在逆元的充要条件是(a,p)=1,特别的,若p是质数,除了扩展欧几里得,还有什么别的方法吗
(1)费马小定理
因为φ(p)=p-1(即p为质数),a,p互质
所以ap-1≡1(mod p)
我们就找到了a的一个逆元ap-2,可以用快速幂求出
附快速幂模板
int bPow(int b){ for(;b;b>>=1,base=(LL)base*base%mod) if(b&1) res=(LL)res*base%mod; return res%mod; }
(2)递推法
这是一个玄学的递推

而p%i的逆元我们已经求出,所以可以得到i的逆元
代码如下
inv[0]=0; inv[1]=1; for(int i=2;i<=n;i++) inv[i]=(p-p/i)*inv[p%i]%p;
这个递推是线性的,非常适合求连续多个数的逆元
2.例题
T1 线性求逆元
T2先通分,维护后缀积和前缀积,求分母的逆元即可,注意卡常
3.总结
求逆元就是解同余方程ab≡1(mod p),这里(a,p)=1;
针对p是质数,还有2种特殊的求法
欢迎大家分享新的求法或是提出不足

浙公网安备 33010602011771号