逆元素是指一个可以取消另一给定元素运算的元素,在数学里,逆元素广义化了加法中的加法逆元和乘法中的倒数。
在要取模大整数的除法中,我们常常会遇到这样一个问题:
(6mod 5=1)
$ 3mod 5=3$
但((6div 3 )mod5=2)
((1div3)mod5=???)
由此可见除法取模运算不能再套用和的模的等于膜的和的模,或是积的模等于模的积的模来算了。
我们知道在除以一个数就是乘以它的倒数,倒数是数学广义定义的逆元,如果我们要对要两个作商的数取模,我们是不是也可以找一个不是分数而和倒数具有相同作用的数呢?这样我们就可以用之前积的模等于模的积的模这个结论算出答案。
exgcd
我们首先把这个问题用数学方法表示出来
其中(a^{-1})是逆元,而我们只要找到一个最小的正整数x,就可以得到逆元了。
补充一个知识:
在同余方程里,满足:如果(gcd(a,p)=1)则 (xequiv ay(mod p))等价于(axequiv ay(mod p))
把之前的式子化一下就可以得到:
现在就变成了一个解同余方程的问题了。
考虑把右边写成写成(-kp+1)的形式,把k和p的名字换成y和b,那么可以转化问题为求不定方程$$ax+by=1$$的解。
我们知道如果a,b互质那么(gcd(a,b)=gcd(b,a\% b)=1)。设(a_1=b,b_1=a\%b,)那么同样对于这一组(a_1,b_1)也可以求解他们对应的(x_1,y_1),接下来找(x_1,y_1)和(x,y)之间的联系。
仿照上面的形式。可以很容易地写出方程。
即$$bx_1+(a-(a/b)*b)y_1=1$$
展开,提出含a含b的项,合并同类项:
对比发现(x=y_1,y=(x_1-(a/b)*y_1))。
一步一步递归求解,到(a_n=1,b_n=0)的时候(x_n)显然就等于1,(y_n)显然为0。
代码很简单:
int x,y;
int exgcd(int a,int b)
{
if(b==0)
{
x=1;y=0;
return a;
}
int r=exgcd(b,a%b);
int t=x;
x=y;
y=t-(a/b)*y;
return r;
}
逆元的线性求法
显然 (e[1]=1);
然后设$p=ki+r,k=lfloor a/b
floor,r=p%i (.
那么)(pequiv0(mod p))$
同乘(i^{-1}r^{-1})
整理得:
代码
e[1]=1;
for(int i=2;i<=n;i++)
{
e[i]=-(p/i)*e[p%i];
e[i]=(e[i]%p+p)%p;
}