Go...

当前位置: 首页>>世界杯太太团

乘法逆元

乘法逆元

Kelier_pkl

·

2022-06-24 20:13:17

·

个人记录

乘法逆元

本文介绍模意义下乘法运算的逆元(Modular Multiplicative Inverse),并介绍如何使用扩展欧几里德算法(Extended Euclidean algorithm)求解乘法逆元

逆元简介

如果一个线性同余方程ax≡1(mod\ b),则称x为a\ mod\ b的逆元,记作a^{-1}

如何求逆元

扩展欧几里得法

可适用于模数不为质数的情况

void exgcd(int a, int b, int& x, int& y) {

if (b == 0) {

x = 1, y = 0;

return;

}

exgcd(b, a % b, y, x);

y -= a / b * x;

}

扩展欧几里得法和求解线性同余方程是一个原理,在这里不展开解释。

快速幂法

只适用于模数为质数,且模数与余数互质的情况

∵$ $ax≡1(mod\ b)

∴$ $ax≡a^{b-1}(mod\ b)

∴$ $x≡a^{b-2}(mod\ b)

【理论依据:费马小定理】

然后我们就可以用快速幂来求了。

inline int qpow(long long a, int b) {

int ans = 1;

a = (a % p + p) % p;

for (; b; b >>= 1) {

if (b & 1) ans = (a * ans) % p;

a = (a * a) % p;

}

return ans;

}

递推法

可适用于模数不为质数的情况

令第i个数的逆元为inv[i],易得:inv[i]=(p-\left\lfloor\dfrac{p}{i}\right\rfloor)×inv[p\%i]\%p

特殊情况:inv[1]=1

下面是一道例题:P3811 【模板】乘法逆元

所以代码如下:

#include

using namespace std;

typedef long long LL;

#define MAXN 3000005

LL n,p;

LL inv[MAXN];

int main(){

scanf("%lld%lld",&n,&p);

inv[1]=1;

printf("1\n");

for(LL i=2;i<=n;i++){

inv[i]=(p-p/i)*inv[p%i]%p;

printf("%lld\n",inv[i]);

}

}