乘法逆元、逆元应用、求逆元(费马小定理,扩展欧几里得)

乘法逆元

对于缩系中的元素,每个数a均有唯一的与之对应的乘法逆元x,使得ax≡1(mod n)
一个数有逆元的充分必要条件是gcd(a,n)=1,此时逆元唯一存在 

逆元的含义:模n意义下,1个数a如果有逆元x,那么除以a相当于乘以x。


逆元的应用

当求解公式:(a/b)%m 时,因b可能会过大,会出现爆精度的情况,所以需变除法为乘法:
设c是b的逆元,则有b*c≡1(mod m);
则(a/b)%m = (a/b)*1%m = (a/b)*b*c%m = a*c(mod m);
即a/b的模等于a* b的逆元 的模;

逆元就是这样应用的;


求逆元的方法

(1)费马小定理

假如p是质数,且gcd(a,p)=1,那么 a(p-1)≡1(mod p),例如:假如a是整数,p是质数,则a,p显然互质(即两者只有一个公约数1),那么我们可以得到费马小定理的一个特例,即当p为质数时候, a^(p-1)≡1(mod p)。(百度百科)

由费马小定理 a(p-1)≡1(mod p)变形得 a*a(p-2)≡1(mod p),若a,p互质,因为a*a(p-2)≡1(mod p)且a*x≡1(mod p),则x=a(p-2)≡1(mod p),故可以用快速幂求得a的逆元。

算法复杂度O(logn)

const int mod = 1000000007;
long long quickpow(long long a, long long b) {
    if (b < 0) return 0;
    long long ret = 1;
    a %= mod;
    while(b) {
        if (b & 1) ret = (ret * a) % mod;
        b >>= 1;
        a = (a * a) % mod;
    }
    return ret;
}
long long inv(long long a) {
    return quickpow(a, mod - 2);
}


(2)拓展欧几里德

扩展欧几里德用于在已知a,b的情况下求解一组x,y,使它们满足贝祖等式: ax + by = gcd(a, b) = d, d是a和b的最大公约数。

我们都知道模就是余数,比如12%5=12-5*2=2,18%4=18-4*4=2。(/是程序运算中的除)

那么ax≡1 (mod p)即ax-yp=1.把y写成+的形式就是ax+py=1,为方便理解下面我们把p写成b就是ax+by=1。就表示x是a的模b乘法逆元,y是b的模a乘法逆元。然后就可以用扩展欧几里得求了。

算法复杂度O(logn)

ll extend_gcd(ll a, ll b, ll &x, ll &y) {  
    if (b == 0) {  
        x = 1, y = 0;  
        return a;  
    }  
    else {  
        ll r = extend_gcd(b, a % b, y, x);  
        y -= x * (a / b);  
        return r;  
    }  
}  
ll inv(ll a, ll n) {  
    ll x, y;  
    extend_gcd(a, n, x, y);  
    x = (x % n + n) % n;  
    return x;  
}  




猜你喜欢

转载自blog.csdn.net/m0_37611893/article/details/80464515