关于乘法逆元的数学知识:
乘法逆元,是指数学领域群G中任意一个元素a,都在G中有唯一的逆元a‘,具有性质a×a'=a'×a=e,其中e为该群的单位元。
例如:4关于1模7的乘法逆元为多少?
4X≡1 mod 7
这个方程等价于求一个X和K,满足
4X=7K+1
其中X和K都是整数。
若ax≡1 mod f, 则称a关于模f的乘法逆元为x。也可表示为ax≡1(mod f)。
当a与f互素时,a关于模f的乘法逆元有解。如果不互素,则无解。如果f为素数,则从1到f-1的任意数都与f互素,即在1到f-1之间都恰好有一个关于模f的乘法逆元。
例如,求5关于模14的乘法逆元:
14=5*2+4
5=4*1+1
说明5与14互素,存在5关于14的乘法逆元。
1=5-4=5-(14-5*2)=5*3-14
因此,5关于模14的乘法逆元为3
关于乘法逆元的代码实现:
1 循环找解法
给定模m和需要求逆的数x,直接暴力枚举1~m-1
检查是否有x*i=1(mod m)
这种算法可以应用与写暴力、对拍、模数较小,求逆次数少的情况
时间复杂度O(m)
2 扩展欧几里得算法
给定模数m,求a的逆相当于求解ax=1(mod m)
这个方程可以转化为ax-my=1
然后套用求二元一次方程的方法,用扩展欧几里得算法求得一组x0,y0和gcd
检查gcd是否为1
gcd不为1则说明逆元不存在
若为1,则调整x0到0~m-1的范围中即可
void ext_gcd(int a,int b,int &d,int &x,int &y){
if (b==0){
d=a;x=1;y=0;
return;
}
ext_gcd(b,a%b,d,y,x);//回代
y-=a/b*x;
}
int main(){
scanf("%d%d",&m,&n);//求m关于n的逆元
ext_gcd(m,n,d,x,y);
printf("%d\n",(x+n)%n);
return 0;
}
这种算法效率较高,常数较小,时间复杂度为O(ln n)