逆元详解(加扩展欧几里得和费马小定理的证明)

最近,wyb小朋友老是不好好搞他的数据结构,跑过来问我数学,没办法,所以我决定每天发一篇数论的博客,骗骗流量(以后wyb有不会的就看我博客,哈哈哈)先从基础的更起吧。

逆元:

我第一次接触逆元是在离散数学的代数系统中,对于一种运算满足(a * a^{-1} = e)\Lambda(a^{-1} * a = e)e为该运算的单位)则称a^{-1}a的逆元。

逆元在算法中的运用:

逆元在算法中主要是为了整数的除法取模,显然除法是不能直接取模的。但是我们可以转化一下,因为乘法是可以直接取模的。

a\ /\ b\ mod \ c\ = a\ *\ b^{-1}\ mod \ c所以我们的问题直接转变成了求b的逆元。

逆元的求法:(此处的逆元是指的模运算的逆元)

1.费马小定理:

a^{p-1}\ =\ 1(mod\ p)\Leftrightarrow a\ *\ a^{p-2}\ =\ 1(mod\ p)(此处的p为素数)

要证明费马小定理,首先我们需要证明对于任意的整数a,b,c有一个素数p满足gcd(c,p)\ =\ 1,使得ac\ =\ bc(mod\ p)\Rightarrow a\equiv b(mod\ p)

\small ac=bc(mod\ p)\Leftrightarrow(a\ mod\ p)*(c\ mod\ p)\equiv(b\ mod\ p)*(c\ mod\ p)\Leftrightarrow a\equiv b(mod\ p)

对p取模的所有数字为\small [0,p-1],又因为0乘任何数等于0所以剔除0,令a为任意正整数都有\prod_{i=1}^{p-1}ia=!(p-1)(mod\ p)\Leftrightarrow !(p-1)a^{p-1}=!(p-1)(mod\ p)\Leftrightarrow a^{p-1}=1(mod\ p)原式得证

如果p为小素数我们选择直接暴力,时间复杂度为O(n)

int Fermat_inverse(int a,int mod)
{
    int res = 1;
    for(int i = 1;i < mod - 1;++i) res *= a;
    return res; 
}

如果p为大素数,我们可以用快速幂求解,时间复杂度为O(logn)

long long fast_pow_mod(long long a,long long b,long long mod)
{
    long long res = 1;
    while(b){
        if(b & 1) res = (res * a) % mod;
        a = (a * a) % mod;
        b >>= 1;
    }
    return res;
}
long long Fermat_inverse(long long a,long long mod)
{
    return fast_pow_mod(a,mod - 2,mod); 
}

2.扩展欧几里得:

对于任意的两个正整数(负整数将负号提至系数)a,b必然存在两个整数x,y使得ax\ +\ by\ =\ gcd(a,b)

懒得再写一篇

猜你喜欢

转载自blog.csdn.net/qq_41791981/article/details/81511434