-
题意 :RT
-
题解:这题比较坑,我用了扩欧和快速幂都T了,后来学习了一种线性算法,用来求一连串数的逆元.
首先我们知道 \(p\equiv0 \;(mod\,p)\) .
设: \(p=k*i +r\),\(k\)是\(p/i\)的商,\(r\)是余数.
于是我们得到\(k*i+r\equiv 0\;(mod\;p)\).
然后乘上\(i^{-1},r^{-1}\)并移项得到:
\(i^{-1}\equiv-k*r^{-1}\;(mod\;p)\) .
\(i^{-1}\equiv-\lfloor\frac{p}{i}\rfloor*(p\;mod\;i)^{-1}\ (mod\;p)\).
而对于\(p\;mod\;i\),一定有\(p\;mod\;i<i\),所以我们用\(f[i]\)来表示\(i\)的逆元.
最后不要忘了取正,因为在等式右边加上\(p\)原式不变,所以最后的公式为:
\(i^{-1}\equiv(p-\lfloor\frac{p}{i}\rfloor)*(p\;mod\;i)^{-1}\ (mod\;p)\).
-
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <stack> #include <queue> #include <vector> #include <map> #include <set> #include <unordered_set> #include <unordered_map> #define ll long long #define fi first #define se second #define pb push_back #define me memset const int N = 30000528; const int mod = 1e9 + 7; using namespace std; typedef pair<int,int> PII; typedef pair<long,long> PLL; ll n,p; ll f[N]; int main() { scanf("%d %d",&n,&p); f[1]=1; puts("1"); for(ll i=2;i<=n;++i){ f[i]=(p-p/i)*f[p%i]%p; printf("%lld\n",f[i]); } return 0; }