数论——逆元

    • 定义
    • 扩展欧几里得求逆元
    • 费马小定理求逆元
      • 证明
      • 代码
    • 线性递推算法
    • 对数级算法求逆元

定义

a×x1(modb) ab 互质,我们就称 x a 的逆元,记作 a1
下面给出逆元的几种求法。

扩展欧几里得求逆元

扩展欧几里得在这里。
因为 a×x1(modb) ,所以 a×x=b×y+1 ,等价于 a×x+b×y=1 ,这就是一个可以用欧几里得求解的线性方程了。
在这里已经介绍出了如何利用原结论求出这个方程的解。
下面给代码:

void exgcd(int a,int b,int c,int &x,int &y)
{
    int ret,tmp;
    if(a==0)
    {
        x=0;
        y=c/b;
        return;
    }
    int tx,ty;
    exgcd(b%a,a,c,tx,ty);
    x=ty-(b/a)*tx;
    y=tx;
    return;
}

费马小定理求逆元

p 是一个素数, a 是和 p 互质的整数,则有:

ap11(modp)

所以我们发现有: a×ap21(modp) ,所以当 p 是素数时候, a 的逆元就是 ap2
注意点:费马小定理在 p 是素数而且 a,p 互质的时候才可以使用。
变式:对任意整数 a ,有 apa(modp) ,我们可以发现,对于这两个结论,我们有这样的条件:
a,p 互质的时候,两个结论是等价的;如果 a,p 不互质,那么只有后者成立。

证明

首先, p1 个整数 a,2a,3a,4a,(p1)a 中没有一个是 p 的倍数。(因为p是质数而且ap还互质)。
其次 a,2a,3a,4a,(p1)a 中没有两个模 p 同余的。
于是这些数再加上 ap 就构成了一个完系。所以 a,2a,3a,4a,(p1)a 在模 p 意义下是 1 p1 的一种排列。
所以: a×2a×3a××(p1)a1×2×3××(p1)(modp)
化简:
ap1×(p1)!(p1)!(modp)
因为 p 是质数,所以 (p1)! p 互质。约分后 ap1(modp)
这个情况只有在 p 是素数而且 ap 互质才成立。一般地,若 p 是质数,则有:
apa(modp)

代码

费马小定理使用的方法就很简单了,快速幂!

线性递推算法

声明:下面所有的运算都是在 modp 意义下进行的。
首先1的逆元是1。接下来我们表示逆元使用这个方法 a1
我们设 p=k×i+r(r<i,1<i<p) 如果把这个式子放在 modp 意义下,则会有 k×i+r0(modp) 两边同乘以 (i1×r1) 就会有:

k×r1+i1i1i10(modp)k×r1(modp)[pi]×(pmodi)1

所以我们就得到了代码:

A[i]=-(p/i)\times A[p % i];

这个方法适用于求多个整数的逆元。

对数级算法求逆元

我们由线性算法可以得到,我们可以不停地使用上述的公式递归,显然可以证明 pmodi<p/2
所以我们发现每次的问题规模都缩小了一半,所以时间复杂度 O(log2p)
代码:

int ny(int i)
{
    return i==1 ? 1 : (-ny(p%i)*p/i)%p;
}

你可能感兴趣的:(数论数学,数论)