乘法逆元定义:
一般来讲,如果要运算加法、减法、乘法、乘方,都应该满足以下式子:
(a+b)%c=(a%c+b%c)%c(a+b)%c=(a%c+b%c)%c
(a−b)%c=(a%c−b%c)%c(a−b)%c=(a%c−b%c)%c
(a⋅b)%c=(a%c⋅b%c)%c(a·b)%c=(a%c·b%c)%c
ab%p=(a%p)b%pab%p=(a%p)b%p
然而这里出现了一个问题:
如果是除法,并不满足(a/b)%c=(a%c/b%c)%c(a/b)%c=(a%c/b%c)%c,不信你代个数试试:
(6/3)%3=2≠(6%3/3%3)%3=RuntimeError(6/3)%3=2≠(6%3/3%3)%3=RuntimeError
那怎么实现对除法的取余呢?
这里就引入乘法逆元这个东西。
他可以达到这样的效果:
(a/b)%k=(a⋅c)%k(a/b)%k=(a·c)%k
你可以将它简单地理解为类似于倒数的东西,只不过是再对倒数取余而已,即:
(b⋅c)%k=1(b·c)%k=1
所以注意,逆元是针对一个数而言的,并不是针对一个表达式。
求法
使用扩展欧几里德算法,但是好像只能在所求的数和取余的数互质才行。
因为:
(b⋅c)%k=1(b·c)%k=1
所以我们可以得到
b⋅c+n⋅k=1b·c+n·k=1
所以只有在bb和kk互质的情况下,才能得到:
b⋅c+n⋅k=gcd(b,k)b·c+n·k=gcd(b,k)
然后用这个方程求解出cc的值,就是所求的乘法逆元。
求79关于3220的乘法逆元:
运行结果:
附录:
java实现:
package oujilide;
public class ojld {
public static int niyuan(int a,int b) //求79关于模3220的乘法逆元
{
int[] m={1,0,a};
int[] n={0,1,b};
int[] temp=new int[3];
int q=0; //初始化
boolean flag=true;
while(flag)
{
q=m[2]/n[2];
for(int i=0;i<3;i++)
{
temp[i]=m[i]-q*n[i];
m[i]=n[i];
n[i]=temp[i];
System.out.print(temp[i]+" ");
}
System.out.println();
if(n[2]==1)
{
if(n[1]<0)
n[1]=n[1]+a;
return n[1];
}
if(n[2]==0)
flag=false;
}
return 0;
}
public static void main(String[] args) {
int result = niyuan(3220,79);
System.out.println();
System.out.println("79关于3220的逆元为:"+result);
}
}