模意义下的乘法逆元
逆元定义: 若 \(a * x \equiv 1 (mod\) \(b)\), 则x为a在模b意义下的乘法逆元
用途:代替除法
求逆元的四种情况:
-
1.扩展欧几里得
-
2.快速幂(费马小定理)
-
3.线性递推
-
4.阶乘情况下的线性递推
一.扩展欧几里得(exgcd)
需要\(a,b\)互质,但是当\(b\)不是质数时也能使用
exgcd:求 \(ax + by = gcd(a, b)\)的整数解
令\(gcd(a, b) = 1\),则\(ax + by = 1\)
可改写为\(ax \equiv 1 (mod\) \(b)\)
故只需求解\(ax + by = 1\) 的一组解
求解方法:
令\(G = gcd(a, b)\)
对\(a, b\)实施一步辗转相除:
设\(x_2\),\(y_2\)满足:\(bx_2 + (a\) \(mod\) \(b)y_2 = G\)
又\(a\) \(mod\) \(b = a - \lfloor \frac{a}{b} \rfloor * b\)
代入得:\(bx_2 + ( a - \lfloor \frac{a}{b} \rfloor * b)y_2 = G\)
整理得: \(ay_2 + b(x_2 - \lfloor \frac{a}{b} \rfloor * y_2) = G\)
比较得 \(x = y_2, y = x_2 - \lfloor \frac{a}{b} \rfloor * y_2\)
故只需求出\(x_2,y_2\)即可求出\(x, y\)
同理,再次实施辗转相除,设出\(x_3\),\(y_3\)即可求出\(x_2,y_2\)
以此类推,直到辗转相除得\(a = G\), \(b = 0\),此时\(x_n = 1, y_n = C\) (通常取C = 0);
故可存储辗转相除得各步骤中a, b得值,再倒序依次求出\(x_n\), \(x_{n - 1}\) ... \(x_1\), \(x\)
可用递归或栈实现
代码:
int x, y;
void exgcd(int a, int b){
if(b == 0){
x = 1;
y = 0;
return ;
}
exgcd(b, a % b);
int t = x;
x = y;
y = t - (a / b) * y;
}
二.快速幂
结论最好记的方法,需要b为质数
费马小定理:若p为素数,a为正整数,且a, p互质,则有 \(a^{p-1} \equiv 1 (mod\) \(p)\)
所以将其带入逆元定义式可得 \(x = a^{p - 2}\), 可使用快速幂求出x
代码:
ll mul(ll x, ll y){
ll res = 1;
while(y){
if(y & 1){
res *= x;
res %= mod;
}
x *= x;
x %= mod;
y >>= 1;
}
return res;
}
int main(){
ll x = mul(a, p - 2);
printf("%d", x);
return 0;
}
三.线性递推
可以求一连串数在模p意义下的乘法逆元
递推式:
inv[i] = (p - p / i) * inv[p % i] % p
推导过程:
设 \(p = k * i + r\) 表示p除以k等于i余r
则该等式可改写为 \(k * i + r \equiv 0\) \((mod\) \(p)\)
两边同乘\(k^{-1} * i^{-1}\)可得 \(i^{-1} \equiv -k * r^{-1}\) \((mod\) \(p)\)
将\(k = \lfloor \frac{p}{i} \rfloor\), \(r = p\) \(mod\) \(i\)代入可得
\(i^{-1} \equiv -\lfloor \frac{p}{i} \rfloor * (p\) \(mod\) \(i)^{-1}\) \((mod\) \(p)\)
inv[1] = 1;
printf("1\n");
for(int i = 2; i <= n; i++){
inv[i] = (p - (p / i)) * inv[p % i] % p;
printf("%lld\n", inv[i]);
}
四。阶乘情况下的线性递推
可以求一连串阶乘的逆元,在组合数中十分常用
递推式为:(需倒推,可先求出最大值)
inv[p] = inv[p + 1] * (p + 1) % p
推导非常简单:
$(i + 1)!^{-1} \equiv (i + 1)!^{-1} \((mod\) \(p)\)
两边同乘\(i + 1\), 得:
\((i + 1)!^{-1} * (i + 1) \equiv (i!)^{-1} (mod\) \(p)\)
inv[MAX] = mul(j[MAX], mod - 2);
for(int i = MAX - 1; i > 0; i--){
inv[i] = inv[i + 1] * (i + 1) % mod;
}
应用补充:有理数取余
题目:P2613
求 \(\frac{a}{b}\) 模p的值,可令\(c = \frac{a}{b}\)即等同于求满足\(x \equiv c (mod\) $x) $
模意义下的除法应写作逆元形式,即\(x \equiv a * b^{-1} (mod\) $x) $

浙公网安备 33010602011771号