乘法逆元入门
Posted ZSYL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了乘法逆元入门相关的知识,希望对你有一定的参考价值。
乘法逆元入门(四种方法及补充)
前言
在一些题目中,因为数据量会特别大甚至超过long long
,所以会要求最后结果mod
一个数,实际上就是让你在计算过程中就要不断mod。
对于加法:
(
a
+
b
)
%
m
=
(
a
%
m
+
b
%
m
)
%
m
(a+b)\\%m = (a\\%m+b\\%m)\\%m
(a+b)%m=(a%m+b%m)%m
对于减法:
(
a
−
b
)
%
m
=
(
a
%
m
−
b
%
m
)
%
m
(a-b)\\%m = (a\\%m-b\\%m)\\%m
(a−b)%m=(a%m−b%m)%m
对于乘法:
(
a
∗
b
)
%
m
=
(
a
%
m
∗
b
%
m
)
%
m
(a*b)\\%m = (a\\%m*b\\%m)\\%m
(a∗b)%m=(a%m∗b%m)%m
但是这个规则在除法不适用:简单例子比如 ( 30 7 ) % 2 (\\frac307)\\%2 (730)%2。
我们一般遇到除法 (a/b)%MOD
的时候,会将除法变为乘法,用到了“逆元”的思想。
逆元
当求解公式:(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);
例如: b = 10 , m = 3 b=10,m=3 b=10,m=3时, c = 4 c=4 c=4
令
a
=
20
,
(
20
/
10
)
%
3
=
2
,
(
20
∗
4
)
%
3
=
2
a=20, (20/10)\\%3=2 ,(20*4)\\%3=2
a=20,(20/10)%3=2,(20∗4)%3=2
令
a
=
40
,
(
40
/
10
)
%
3
=
1
,
(
40
∗
4
)
%
3
=
1
a=40, (40/10)\\%3=1 ,(40*4)\\%3=1
a=40,(40/10)%3=1,(40∗4)%3=1
现在我们要求 ( a / b ) % m (a/b)\\%m (a/b)%m,可以找到一个 c c c使得 ( a / b ) % m = ( a ∗ c ) % m (a/b)\\%m=(a*c)\\%m (a/b)%m=(a∗c)%m.
费马小定理
如果 p p p是一个质数,而整数 a a a不是 p p p的倍数,则有 a p − 1 ≡ 1 ( m o d ) p a^p-1 ≡ 1(mod)p ap−1≡1(mod)p
所以可得: a p − 2 ≡ a − 1 ( m o d p ) a^p-2≡a^-1(mod p) ap−2≡a−1(modp)
换成代码如下:
(a/b)%m
(a*pow(b,m-2))%m
这里还需要快速幂来配合计算:
ll quick_pow(ll x,ll n,ll m)
ll res = 1;
while(n > 0)
if(n & 1)
res = res * x % m;
x = x * x % m;
n >>= 1;
return res;
ll inv(ll a)
return quick_pow(a, mod - 2, mod);
递归
当m是质数,inv(a) = (m - m / a) * inv(m % a) % m
,暴力反向递归
ll inv2(ll a,ll m)//代入a%m m
return a==1?1:(m-m/a)*inv2(m%a,m)%m;
线性递推
求关于一个m的多个逆元,道理差不多:
ll m=3;
ll inv[m+5];
void inv3(ll m)
inv[1]=1;
for(int i=2;i<m;i++)
inv[i]=(m-m/i)*inv[m%i]%m;
参考:Link
加油!
感谢!
努力!
以上是关于乘法逆元入门的主要内容,如果未能解决你的问题,请参考以下文章