乘法逆元的几种求法
知乎乘法逆元
博客园乘法逆元多了阶乘方法
一·扩展欧几里得算法
已知a,b,找到x,y使它们满足贝祖等式:
首先因为b不等于0,
如果有一组解x',y'使得
那么
因为
所以:
变形
然后就得到一组特解:
上面的过程不断的递归下取,一直到b=0为止,此时表达式为
代码
void Exgcd(ll a, ll b, ll &x, ll &y) {
if (!b) x = 1, y = 0;
else Exgcd(b, a%b, y, x),y -= a / b * x;
}
int main()
{
ll x, y;
Exgcd(a, p, x, y);
x = (x%p + p) % p;//注意x可能为负数
cout << x << endl;
return 0;
}
二·快速幂 费马小定理
费马小定理:如果p为素数,a为正整数且a,p互质,那么
那么可以提一个a出来,它是要求乘法逆元的数;
所以a的乘法逆元就是
代码
inline ll qpow(ll a, ll n, ll p)// 快速幂
{
ll ans = 1;
while (n)
{
if (n & 1)
ans = ans % p * a % p;
a = a % p * a % p;
n >>= 1;
}
return ans;
}
inline ll inv(ll a, ll p)
{
return qpow(a, p - 2, p);
}
三·线性算法(对于求一连串的乘法逆元)
首先1的乘法逆元是1
设
将式子放在
两边乘上
代码
inv[1] = 1;
for(int i = 1; i < p; ++ i)
inv[i] = (p - p / i) * inv[p % i] % p;