乘法逆元
定义
如果有\(a x \equiv 1(\bmod b)\),则称\(x\)为\(a \ mod \ b\)的逆元,记作\(a^{-1}.\)
性质
\[\frac{x}{y} \equiv x \times y^{-1} \quad(\bmod p)
\]
计算方法
- 扩展欧几里得
限制:
\[gcd(a,b)=1
\]
#include <iostream>
using namespace std;
void Exgcd(int a , int b , int &x , int &y){
if(!b) x = 1 , y = 0;
else Exgcd(b , a % b , y , x) , y -= (a / b) * x;
}
int main(){
int n , p , x , y;
ios::sync_with_stdio(false);
cin >> n >> p;
for(int i = 1; i <= n; i++){
Exgcd(i , p , x , y);
while(x < 0) x += p;
x %= p;
cout << x << endl;
}
return 0;
}
- 快速幂
运用费马小定理:
若\(p\)为质数,\(a\)为正整数,且\(a,p\)互质,则\(a^{p-1} \equiv 1 \ ( \bmod \ p)\)
由\(ax \equiv 1\ (\bmod\ b)\)且\(\ a^{b-1} \equiv 1\ (\bmod\ b),\)
得\(a x \equiv a^{b-1}\ (\bmod\ b),\)
得\(x \equiv a^{b-2}\ (\bmod\ b).\quad\)故可用快速幂求解:
int fpm(ll a, ll b, ll p){
ll ans = 1; a %= p;
for(; b; b >>= 1,(a *= a) %= p) if (b & 1) (ans *= a) %= p;
return ans;
}
int main(){
ll x = fpm(a, p - 2, p);//x为a在mod p意义下的逆元
}
-
线性求逆元
用于求一连串数字对于一个相同模数$\ p\ $的逆元
显然,\(1^{-1} \equiv 1\ (\bmod\ p)\)
设\(\ p=k * i+r\ ,(1<r<i<p),\)那么在\((mod\ p)\)意义下有
\[k * i+r \equiv 0 \quad(\bmod\ p) \]两侧同乘\(i^{-1},r^{-1}\)得
\[k * r^{-1}+i^{-1} \equiv 0 \quad(\bmod\ p) \]\[i^{-1} \equiv-k * r^{-1} \quad(\bmod\ p) \]\[i^{-1} \equiv-\left\lfloor\frac{p}{i}\right\rfloor *(p \bmod i)^{-1} \quad(\bmod\ p) \]可以得到递推代码:
inv[1] = 1; for(int i = 2; i < p; ++ i) inv[i] = (p - p / i) * inv[p % i] % p;

浙公网安备 33010602011771号