日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【乘法逆元】取模运算

發布時間:2024/1/1 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【乘法逆元】取模运算 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一,定義

1 逆元:

在群G中,?a∈G,?a′∈G,s.t.aa′=e,其中e為G的單位元。

2 乘法逆元:

p為素數,記a?b=a×bmodp在群(N,?)(N,·)中,?a∈N,?a′∈N,s.t.aa′=e=1?a∈N,?a′∈N,s.t.aa′=e=1。則稱a′是a關于modp的逆元。
為了方便表示,且下面的內容都只涉及到相同的p,我們記a關于modp的逆元為inv[a]。

二, 作用

情況1:

在算法競賽中,經常會遇到求解數據很大,則輸出模 [公式] 的解這類要求。加法、減法、乘法等操作,基于同余理論直接取模即可。但遇到除法時,某步中間結果不一定能完成整除,就無法求解了。
對于(36/3%7)的情況。
第一步,36=18,18%7=4。
第二步,4/3無法整除,但是我們可以求出除數3關于模數7的逆元5,35%7=1符合逆元的定義。
所以我們用5代替/3,即4*5=20,而20%7=6,得到正確答案。

*** 對于一個大數m,在計算m/a%b時,對于a的逆元d可以有m*d%b=m/a%b。對于需要在計算中取模并且有除法的題目中非常好用。 ***

情況2:

當我們要求ab的值時,知道答案的范圍ans≤k,但是a和b太大無法直接計算。這時候我們就要假設出一個質數L>k,然后求abmodL即可。

三, 求法

1.枚舉法

2.快速冪(費馬小定理)

歐拉定理,a^?(p)=1(modp)

∴ap?1≡1(modp)
∴a^p?1≡1(modp)
∴a×a(p?2)≡1(modp)∴a×a^(p?2)≡1(modp)
根據逆元的存在唯一性,inv[a]≡a^p?2(modp)
** 適用:如果n nn是一個質數,而整數a aa不是n nn的倍數**

#include <cstdio> int a,p; int Pow(int i,int j) {if (!j) return 1;int now=Pow(i,j>>1);now=now*now%p;if (j&1) now=now*i%p;return now; } int main(void) {scanf("%d%d",&a,&p);printf("%d\n",Pow(a,p-2));return 0; }

3.擴展歐幾里得算法

aa′≡1(modp) ,我們只用找到ax+py=1(ax=-py+1),而a′≡x。
對于ax+py=1中x,y的找法就是擴展歐幾里得算法。
我們對a,p最大公約數,順便維護x和y的值。
** 適用:存在逆元即可求,適用于個數不多但模數b很大的時候,最常用、安全的求逆元方式。**

#include <cstdio> int a,p; int x,y; void exgcd(int a,int b) {if (!b) {x=1,y=0;return;}exgcd(b,a%b);int _x=x,_y=y;x=_y,y=_y*(a/b)-_x;x%=p,y%=p; } int main(void) {scanf("%d%d",&a,&p);exgcd(a,p);printf("%d\n",(x+p)%p);return 0; }

4.線性遞推求逆元

** 公式: i n v [ i ] = ( p ? p / i ) × i n v [ p % i ] % p , i n v [ 1 ] = 1 **
** 用途:可以 O ( n ) 預處理出 [1,n] 所有數的關于模 p 的乘法逆元 **
**適用范圍:mod數是不大的素數而且多次調用,比如盧卡斯定理。 **

long long inv[N]; int main(){int n,p;cin>>n>>p;inv[1]=1;for(int i=2;i<=n;i++)inv[i]=(p-p/i)*inv[p%i]%p;for(int i=1;i<=n;i++)printf("%d\n",inv[i]);return 0; }

4,遞歸求逆元

用途: mod數是素數,所以并不好用,比如中國剩余定理中就不好使,因為很多時候可能會忘記考慮mod數是不是素數。

LL inv(LL i) {if(i==1)return 1;return (mod-mod/i)*inv(mod%i)%mod; }

5,線性求逆元

當用逆元的次數比較多時,一直l o g loglog求可能會T TT,這時線性求出來逆元是個不錯的選擇

void init() {inv[1] = 1;for (int i = 2; i <= N; i ++)inv[i] = mul(dec(mod, mod / i), inv[mod % i]); }

總結

以上是生活随笔為你收集整理的【乘法逆元】取模运算的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。