求乘法逆元

对于ax ≡ 1 (mod n),使得同余方程成立的x称为a关于n的逆元。那么我们就可以像解一次同余方程那样将其转化为ax + kn = 1,然后用exgcd求解。

同时,我们发现一件不得了的事,根据exgcd的知识,ax + kn = 1存在解的充要条件是gcd(a, n) = 1,即a和n互质。

如果n是质数,就可以结合费马小定理求解。ax % n = a^(n - 1) % n = 1,则x = a^(n - 2) % n。

但有时我们需要求出某段区间在模n意义下的逆元,此时就有一个可以在线性时间内预处理出某段区间内各个元素逆元的方法。

inv[1] = 1;
for (int i = 2; i <= n; ++i) inv[i] = (p - p / i) * inv[p % i] % p;
//n是区间右边界,p是模数,inv[i]是i关于p的逆元

推导如下:

设a = p / i,b = p % i,则a * i + b ≡ 0 (mod p),(-a) * i ≡ b (mod p),两边同时除以b*i,(-a) * inv[b] ≡ inv[i] (mod p),最后将a和b换掉,就可以得出式子。

需要说明的是,这个程序并不会求出1到n所有元素的逆元,而是求出其在模p剩余系等价类的逆元。比如他不会求4关于3的逆元,因为4%3=1,他只会去求1的逆元。

原文地址:https://www.cnblogs.com/Mr94Kevin/p/9723544.html