逆元總結


乘法逆元,有 一個作用就是,除以一個數再取模時,可以將這個數乘以這個數的逆元再取模,就是將除法運算轉化為乘法運算,舉個例子:

 先說一下什么是逆元:若對於數字A,C 存在X,使A * X ≡ 1 (mod C) ,那么稱X為 A 對C的乘法逆元。

比如:( 4 , 7 ) 的逆元是2,4*2≡ 1(mod 7)

          12 / 4mod 7=(12 / 4)* (4 * 2) mod 7 

這樣看除法就被轉化為乘法了;

關於逆元有三種求法:

1、費馬小定理 (O(nlogn)的復雜度,但若n達到1e7會爆炸,所以需要線性求逆元的方法)

根據費馬小定理,我們可得出當p是素數時,對任意x,都有x^(p)≡  x(modp),

 

若x無法被p整除,那么x^(p-1)≡  1(modp),

那么可得出當模數p為素數x^(p-2)就是x的逆元。

代碼如下:

const ll mod=1e9+7; ll pow_mod(ll a,ll b) { ll res=1; while(b>0) { if(b&1)res=res*a%mod; a=a*a%mod; b>>=1; } return res; } ll inv(ll a) { return pow_mod(a,mod-2); }

2、擴展歐幾里德算法

a*x + b*y = 1

如果ab互質,有解。

那么兩邊同時modp

ax%p≡1%p那么ax≡1(modp)

x就是a關於b的逆元

 

ll x,y,mod; ll extgcd(ll a,ll b,ll& x,ll& y) { ll d=a; if(b!=0) { d=extgcd(b,a%b,y,x); y-=(a/b)*x; } else x=1,y=0; return d; } ll inv(ll a) { ll d=extgcd(a,mod,x,y); return d==1?(x%mod+mod)%mod:-1; } int main() { while(cin>>x>>mod) { cout<<inv(x)<<endl; } return 0; }

 

3、逆元線性篩法

 用來求1,2,3....n關於p的逆元,復雜度O(n)

#define MAX 2005
const ll mod=1e9+7; int inv[MAX]; int main() { ll x; inv[1]=1; for(int i=2;i<MAX;i++) inv[i]=inv[mod%i]*(mod-mod/i)%mod; while(cin>>x) { cout<<inv[x]<<endl; } return 0; }

 

以上的代碼均是本人測試過,如有錯誤,歡迎指正!

參考博客:https://blog.csdn.net/qq_37632935/article/details/77806853

                 https://blog.csdn.net/nucshiyilang/article/details/62044362

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM