P3811 【模板】乘法逆元
本题只能用线性筛逆元,其他方法的话超时,不过还是写出来
线性筛逆元
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn = 3e6+5; 5 int inv[maxn]; 6 int main() { 7 int n, p; scanf("%d%d",&n,&p); 8 inv[1] = 1; puts("1"); 9 for (int i = 2; i <= n; ++i) { 10 inv[i] = (ll)(p-p/i)*inv[p%i]%p; 11 printf("%d\n",inv[i]); 12 } 13 return 0; 14 }
费马小定理+快速幂
#include <bits/stdc++.h> using namespace std; typedef long long ll; ll qpow(ll a, ll b, ll mod) { ll res = 1; while (b) { if (b & 1) res = res*a%mod; a = a*a%mod; b >>= 1; } return res; } int main() { int n, p; scanf("%d%d",&n,&p); puts("1"); for (int i = 2; i <= n; ++i) { printf("%lld\n",qpow(i,p-2,p)); } return 0; }
扩展欧几里得
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 void exgcd(ll a, ll b, ll &x, ll &y) { 5 if (b == 0) x = 1, y = 0; 6 else exgcd(b, a%b, y, x), y -= a/b * x; 7 } 8 int main() { 9 int n, p; scanf("%d%d",&n,&p); 10 puts("1"); 11 for (int i = 2; i <= n; ++i) { 12 ll x, y; 13 exgcd(i,p,x,y); 14 if (x < 0) x += p; 15 printf("%lld\n",x); 16 } 17 return 0; 18 }