乘法逆元总结
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> int n, p, x, y, inv[101010], iNv[101010], fac[101010]; //欧拉定理求逆元 inline long long fast_pow(int a, int b) { long long ans = 1; while (b) { if (b & 1) ans = (a * ans) % p; a = (a * a) % p; b >>= 1; } return ans; } //扩展欧几里得求逆元 void ex_gcd(int a, int b, int & x, int & y) { if (b == 0) { x = 1, y = 0; return; } ex_gcd(b, a % b, y, x); y -= a / b * x; } //线性推逆元 void INV() { inv[1] = 1; for (int i = 2; i <= n; ++i) inv[i] = inv[p % i] * (p - p / i) % p; } //线性求阶乘逆元 void INVV() { fac[0] = 1; for (int i = 1; i <= n; ++i) fac[i] = (fac[i - 1] * i) % p; iNv[n] = fast_pow(fac[n], p - 2); for (int i = n - 1; i >= 1; --i) iNv[i] = (iNv[i + 1] * (i + 1)) % p; } signed main() { std::cin >> n >> p; ex_gcd(n, p, x, y); printf("扩展欧几里得:%d\n", x % p); printf("欧拉定理:%d\n线性推逆元:", fast_pow(n, p - 2)); INV(); INVV(); for (int i = 1; i <= n; ++i) printf("%d ", inv[i]); printf("\n线性推阶乘逆元:"); for (int i = 1; i <= n; ++i) printf("%d ", iNv[i]); return 0; }