P3811 【模板】模意义下的乘法逆元
题目描述
给定正整数 \(n,p\),求 \([1,n]\) 中所有整数在模 \(p\) 意义下的乘法逆元。
\(a\) 模 \(p\) 的乘法逆元定义为 \(ax\equiv1\pmod p\) 的解。
扩展欧几里得算法
#include <iostream>
int exgcd(int a, int b, int &x, int &y) {
if (b == 0) {
x = 1;
y = 0;
return a;
}
int d = exgcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
int main() {
int n = 0;
int p = 0;
// std::cin >> n >> p;
scanf("%d %d", &n, &p);
for (int i = 1; i <= n; i++) {
int x = 0;
int y = 0;
int d = exgcd(i, p, x, y); // ix + py = 1
x %= p;
if (x < 0) x += p;
// std::cout << x << std::endl;
printf("%d\n", x);
}
return 0;
}
- 遍历\(i=1,\cdots,p-1\),针对于每一个\(i\)使用扩展欧几里得算法求解\(ix+py=gcd(i,p)=1\)的解,对于其中的\(x\)规约到\(p\)的简化剩余系中即可,这个代码有一个样例过不了。
- 时间复杂度:\(O(n\ log\ p)\)
- 空间复杂度:\(O(1)\)
线性递推求逆元
将\(p\)对\(i\)进行带余除法:\((p\ is\ a\ prime)\ and\ (i<p)\rightarrow p=k\cdot i+r(0<r<i)\),其中\(k=\lfloor {p\over i}\rfloor\),\(r=p\% i\)。
\[\begin{flalign}
& p=k\cdot i + r\rightarrow k\cdot i + r\equiv0\pmod{p}\rightarrow k\cdot i\equiv -r\pmod{p}\\
& \xrightarrow[\times r^{-1}\pmod{p}]{\times i^{-1}\pmod{p}}k\cdot r^{-1}\equiv -i^{-1}\pmod{p}\rightarrow i^{-1}\equiv -k\cdot r^{-1} = -\lfloor{p\over i}\rfloor\cdot (p \% i)^{-1}\pmod{p}\\
& \rightarrow i^{-1}\equiv (p-\lfloor{p\over i}\rfloor)\cdot(p\%i)\pmod{p}
\end{flalign}
\]
#include <iostream>
#include <vector>
int main() {
int n = 0;
int p = 0;
scanf("%d %d", &n, &p);
std::vector<int> inv(n + 1, 0);
inv[1] = 1;
for (int i = 2; i <= n; i++) {
inv[i] = (long long)(p - p / i) * inv[p % i] % p;
}
for (int i = 1; i <= n; i++) {
printf("%d\n", inv[i]);
}
return 0;
}
- 时间复杂度:\(O(n)\)
- 空间复杂度:\(O(n)\)

P3811 【模板】模意义下的乘法逆元
浙公网安备 33010602011771号