逆元的求法
逆元:
對于a和p,若 a * inv(a) % p ≡ 1,則稱inv(a)為a%p的逆元。其中p為質(zhì)數(shù)
逆元就是在mod下,不能直接除以一個數(shù),而要乘以他的逆元
a * inv(a) = 1 (mod p)
x / a可以改成 x * inv(a) % p
文章目錄
- 方法一.擴(kuò)展歐幾里得
- 代碼:
- 方法二.費馬小定理+歐拉定理
- 代碼:
- 方法三:遞推求逆元
- 代碼
方法一.擴(kuò)展歐幾里得
a * inv(a) = 1 (mod p)
可以變形成 a * inv(a) +k * p = 1(前提是a和p要互素)
可以用擴(kuò)歐的公式來計算
時間復(fù)雜度:O(logn)
適用范圍:只要存在逆元即可求,適用于個數(shù)不多但是mod很大的時候,也是最常見的一種求逆元的方法。
代碼:
ll exgcd(ll a,ll b,ll &x,ll &y)//擴(kuò)展歐幾里得算法 {if(b==0){x=1;y=0;return a; //到達(dá)遞歸邊界開始向上一層返回}ll gcd=exgcd(b,a%b,x,y);ll y1=y; //把x y變成上一層的ll x1=x;y=x1-(a/b)*y1;x=y1;return gcd; //得到a b的最大公因數(shù) } ll inv(ll a,ll mod){ll x,y;ll gcd=exgcd(a,mod,x,y);if(gcd!=1)return -1;else return (x+mod)%mod; }方法二.費馬小定理+歐拉定理
費馬小定理:假如p是質(zhì)數(shù),且gcd(a,p)=1,那么 a(p-1) ≡ 1(mod p),進(jìn)一步可以推出ap-2 * a ≡ 1 (mod p)
ap-2就是a在mod p意義下的逆元
歐拉函數(shù):aφ(n)≡1 (mod n) ,其中 gcd(a,n)=1
若n為素數(shù),φ(n)=n-1
時間復(fù)雜度 O(log mod)
適用范圍:在mod是素數(shù)的時候使用,比擴(kuò)歐快
代碼:
ll poww(ll a,ll b,ll mod){ll ans=1;ll base=a;while(b){if(b&1)ans=ans*base%mod;base=base*base%mod;b>>=1;}return ans%mod; } ll inv(ll a,ll mod){return poww(a,mod-2,mod); }方法三:遞推求逆元
時間復(fù)雜度為O(n)
使用條件:mod為不是很大的素數(shù),且需要多次調(diào)用
代碼
long long inv[maxn]; void init(long long n,long long p) {inv[1]=1;for(int i=2;i<=n;i++){inv[i]=((p-p/i)*inv[p%i]%p);} } 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
- 上一篇: 盘点那些跨界玩到飞起的程序员们!
- 下一篇: 小a的旅行计划