线性求逆
线性求逆
简单来说就是 \(O(n)\) 时间内求出多个数的逆元。
推式子
假设模数是 \(p\) 。
现在要求 \(i^{-1}\) ,有 \(i\le p\) ,记 \(p=k\times i+r\) ,其中 $k=\lfloor{\frac{i}{p}}\rfloor,r=p \mod i $。
两边同时乘以 \(i^{-1},r^{-1}\) 并且放到模数意义下得到:\(i^{-1}=-\lfloor{\frac{i}{p}}\rfloor\times({p\mod i})\)。
然后就可以递推了。
阶乘的逆元公式
可以用exgcd求,也可以用费马小定理求。
首先需要知道 \((n+1)^{-1}\times (n+1) =n^{-1} \mod p\),然后就可以先算出最大的数的逆元,然后倒着递推了。。
Code
#include<bits/stdc++.h>
using namespace std;
long long inv[4000010];
int main()
{
long long n,p;
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>p;
inv[1]=1;
for(int i=2;i<=n;++i)inv[i]=(-p/i+p)%p*inv[p%i]%p;
for(int i=1;i<=n;++i)cout<<inv[i]<<'\n';
return 0;
}
为什么要练,为什么要写?
引用一句让我幡然悔悟的话:
“练了不一定写的出来正解,不练一定写不出来正解”
本文来自博客园,作者:Hanggoash,转载请注明原文链接:https://www.cnblogs.com/Hanggoash/p/18762723

浙公网安备 33010602011771号