乘法逆元

摘要:
为什么引入乘法逆元?
乘法逆元的定义
将除法转换为乘法,就可以用分配律将大数拆成小数再取模
问:如何求乘法逆元x呢?
方法:费马小定理,扩展欧几里得,线性递推等

乘法逆元

图片[1] - 乘法逆元 - MaxSSL
图片[2] - 乘法逆元 - MaxSSL
图片[3] - 乘法逆元 - MaxSSL

费马小定理证明

图片[4] - 乘法逆元 - MaxSSL

费马小定理

图片[5] - 乘法逆元 - MaxSSL

举例

图片[6] - 乘法逆元 - MaxSSL
图片[7] - 乘法逆元 - MaxSSL

代码实现

#include typedef long long ll;//快速幂取模ll fast_pow(ll a, ll b, ll p){    //a^b%p    ll ans = 1;    while(b){        if(b & 1){            //若b是奇数(b%2 == 1),则ans单独乘a,b-=1变成偶数            ans = (ans * a) % p;        }        a = (a * a) % p;        b >>= 1;//(b/=2)b减半    }    return ans;}//费马小定理求逆元 x = a^(p-2) % p;(p必须是质数)ll get_inv(ll a, ll p){    return fast_pow(a, p-2, p);}

扩展欧几里得欧几里得

图片[8] - 乘法逆元 - MaxSSL
图片[9] - 乘法逆元 - MaxSSL

扩展欧几里得

图片[10] - 乘法逆元 - MaxSSL
图片[11] - 乘法逆元 - MaxSSL

举例

图片[12] - 乘法逆元 - MaxSSL

代码实现

#include void exgcd(const int a, const int b, int &g, int &x, int &y){    if(b == 0){ g = a; x = 1; y = 0;}    else {        exgcd(b, a%b, g, y, x);        y -= x * (a/b);    }}int get_inv(const int a, int p){    int g, x, y;    exgcd(a, p, g, x, y);    return (x%p + p) % p;}

线性求逆元推导

图片[13] - 乘法逆元 - MaxSSL
图片[14] - 乘法逆元 - MaxSSL

代码实现

int inv[MAXN];inv [1] = 1;for(int i = 2; i <= n; i++){    inv[i] = -(p / i) * inv[p % i];    inv[i] = (inv[i] % p + p) % p;}
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享