集结号游戏官网首页 当前位置:首页>集结号游戏官网首页>正文

集结号游戏官网首页

发布时间:2019-03-25

原标题:深入浅出乘法逆元

深入浅出乘法逆元


深入浅出乘法逆元
 1.模的运算律
 2.定义
 3.求解
  3.1费马小定理
  3.2扩展欧几里得算法
  3.3线性求解

深入浅出乘法逆元

模的运算律

先来一波模运算律表:

运算律 内容
交换律 ((a+b)\%p=(b+a)\%p)
((a imes b)\%p=(b imes a)\%p)
结合律 (((a+b)\%p+c)\%p=(a+(b+c)\%p)\%p)
(((a imes b)\%p imes c)\%p=(a imes (b imes c)\%p)\%p)
分配率 (((a+b)\%p imes c)\%p=((a imes c)\%p+(b imes c)\%p)\%p)
((a imes b)\%p=(a\%p imes b\%p)\%p)
((a+b)\%p=(a\%p+b\%p)\%p)
((a-b)\%p=(a\%p-b\%p)\%p)

定义

有的时候我们需要对一个数取模,这很简单。但是在取模的过程中出现了除数,那么取模就没这么简单了:
[frac{7}{2}\%4=3\%4=3]注意:(frac{7\%4}{2}=frac{3}{2}=1)错误的
但万一是(frac{7^{10000}}{2}\%4)计算机可无法先计算(frac{7^{10000}}{2})(pmod4),因为数字太大了。
这个时候我们就需要用到乘法逆元了,事实上:(frac{7^{10000}}{2}=(7*3)^{10000})。我们运用模的运算律可以通过边乘边取模即可得到答案,其中3是7在(pmod 4)意义下的逆元。
关于逆元的严格定义如下:

(若整数b,m互质,并且bmid a,则存在整数x,使得a/bequiv a*xpmod m,则称x为b的模m乘法逆元,记为b^{-1}pmod m)

求解

3.1费马小定理

1
因为(a/bequiv a*b^{-1}equiv a/b*b*b^{-1}pmod m),所以(b*b^{-1}equiv 1pmod m)2
如果m是质数(此时我们用符号(p)代替(m))并且(b<p),根据费马小定理(b^{p-1}equiv 1pmod p),即(b*b^{p-2}equiv1pmod p)。因此,当模数(p)为质数时,(b^{p-2})(b)的乘法逆元。
到最后我们可以用快速幂来迅速求出(b^{p-2})。代码如下:

int ksm(int a,int b,int p) {
    int ans=1;
    for(; b; b>>=1,a=a*a%p)if(b&1)ans=ans*a%p;
    return ans;
}

时间复杂度是(O(log n))

3.2扩展欧几里得算法

扩展欧几里得算法的具体内容参考我写的:浅析扩展欧几里得算法(exgcd)
根据逆元的定义我们要求的是(a*xequiv1pmod m)关于x的同余方程,其中x为a在(pmod m)意义下的逆元
事实上[ax=my+1······①]也就是(axdiv m=y······1)
变形①式得:[ax-my=1]
既然(a,b)都已知,就不难求出(x和y)了(但要注意(y)的系数(-b)必须是正整数,因为在计算机计算过程中如果模数是负的将导致结果出错)如果(-b)不是正整数,我们同时改变(a,b)的符号即可。扩展欧几里得算法代码如下:

int exgcd(int a,int b,int &x,int &y) {
    if(b) {
        int c=exgcd(a,b,y,x);
        y-=a/b*x;
        return c;
    } else {
        x=1;
        y=0;
        return a;
    }
}

时间复杂度是(O(ln n))

3.3线性求解

当我们需要求解大量的逆元的时候,前两种的方法时间复杂度都要乘以(n),时间复杂度都不是很理想。所以我们就用(O(n))的时间来快速求解。具体做法如下:假设我们要求x的逆元,那么:[m=k*x+r][k*x+requiv0pmod m]同乘以(x^{-1}*r^{-1})得:[k*r^{-1}+x^{-1}equiv0pmod m······①]将②式变形得:[x^{-1}equiv-k*r^{-1}pmod m]
所以我们得到:[x^{-1}=-lfloor m/x floor*(m\%x)^{-1}]
那么只要建一个数组inv,初始值inv[1]=1。所以代码如下:

    for(int i=2; i<=n; i++)
        inv[i]=-(p/i)*inv[p%i];

  1. 这种方法的常数比较大。↩

  2. (b^{-1}equiv b^{-1}pmod m)其中前一个是(div b),后一个是(a)的逆元(b);根据模的运算律((a/b*b*b^{-1})\%m=((a/b)\%m*((b*b^{-1})\%m)\%m),显然((b*b^{-1})\%m=1)

当前文章://01hms.html

发布时间:2019-03-25 05:36:59

美高梅网上娱乐 千赢国际娱乐pt平台 - 欢迎您 pt客户端下载 千赢app下载安装 经纬娱乐登录地址 

责任编辑:侯文

随机推荐