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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

逆元~(乘法逆元及其应用)

發布時間:2025/3/15 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 逆元~(乘法逆元及其应用) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

數論倒數,又稱逆元(因為我說習慣逆元了,下面我都說逆元)

先來引入求余概念

(a + ?b) % p = (a%p + ?b%p) %p ?(對)

(a ?-? b) % p = (a%p ?- ?b%p) %p ?(對)

(a ?* ?b) % p = (a%p * ?b%p) %p ?(對)

(a ?/ ?b) % p = (a%p ?/ ?b%p) %p ?(錯)

?

為什么除法錯的

證明是對的難,證明錯的只要舉一個反例

(100/50)%20 = 2 ? ? ? ≠ ? ? ?(100%20) / (50%20) %20 = 0

對于一些題目,我們必須在中間過程中進行求余,否則數字太大,電腦存不下,那如果這個算式中出現除法,會損失精度,導致答案變小。

?

這時就需要逆元了

我們知道,如果a*x = 1那么x是a的倒數,x = 1/a但是a如果不是1,那么x就是小數那數論中,大部分情況都有求余,所以現在問題變了a*x ?= 1 (mod p)那么x一定等于1/a嗎?不一定。所以這時候,我們就把x看成a的倒數,只不過加了一個求余條件,所以x叫做 ? ?a關于p的逆元。這時就需要逆元

我們知道,如果a*x = 1那么x是a的倒數,x = 1/a。但是a如果不是1,那么x就是小數,那數論中,大部分情況都有求余,所以現在問題變了,a*x ?= 1 (mod p),那么x一定等于1/a嗎?不一定

所以這時候,我們就把x看成a的倒數,只不過加了一個求余條件,所以x叫做 ? ?a關于p的逆元。比如2 * 3 % 5 = 1,那么3就是2關于5的逆元,或者說2和3關于5互為逆元。這里3的效果是不是跟1/2的效果一樣,所以才叫數論倒數

?

a的逆元,我們用inv(a)來表示。

那么(a ?/ ?b) % p = (a * inv(b) ) % p = (a % p * inv(b) % p) % p

這樣就把除法,完全轉換為乘法了,乘法超容易

a和p互質,a才有關于p的逆元

乘法逆元及其應用

  滿足?a * k ≡ 1 (mod p)?k?叫做?a關于p的乘法逆元。另一種表達方法是?k ≡ a-1?(mod p)

應用:

我們知道(a+b)%p=(a%p+b%p)%p

    (a*b)%p=(a%p)*(b%p)%p

而求(a/b)%p時,可能會因為a是一個很大的數,不能直接算出來,卻又不能(a/b)%p=(a%p/b%p)%p。

但是可以通過?k ≡ b-1?(mod p)?

a / b

= a * b-1?(mod p?)

=?(a?mod p?) * (b-1?mod p?)??mod p

?

=?(a?mod p?) * (k?mod p?)??mod p

= a * k mod p

轉換為a*k % p 的問題,然后a是一個加減乘的式子,就可以用上面兩個取余公式了。

正篇開始:

逆元怎么求?

?

方法一:(滿足p為質數)

費馬曾經說過:不想當數學家的數學家不是好數學家(( ̄▽ ̄)~*我隨便說的,別當真)

費馬小定理(因為費馬小定理的前提 就是 p為質數)

a^(p-1) ≡1 (mod p)

兩邊同除以a

a^(p-2) ≡1/a (mod p)

什么?這可是數論,還敢寫1/a

應該寫a^(p-2) ≡ inv(a) (mod p)

?

所以inv(a) = a^(p-2) (mod p)

這個用快速冪求一下,復雜度O(logn)(? ??_??)??

LL pow_mod(LL a, LL b, LL p){//a的b次方求余p LL ret = 1;while(b){if(b & 1) ret = (ret * a) % p;a = (a * a) % p;b >>= 1;}return ret; } LL Fermat(LL a, LL p){//費馬求a關于b的逆元 return pow_mod(a, p-2, p); }

方法二:(p可以不是質數)

?

要用擴展歐幾里德算法

還記得擴展歐幾里德嗎?(不記得的話,歐幾里得會傷心的(╭ ̄3 ̄)╭?)

?

a*x + b*y = 1

如果ab互質,有解

?

這個解的x就是a關于b的逆元

y就是b關于a的逆元

為什么呢?

?

你看,兩邊同時求余b

?

a*x % b + b*y % b = 1 % b

a*x % b = 1 % b

a*x = 1 (mod b)

?

你看你看,出現了!!!(/≥▽≤/)

所以x是a關于b的逆元

反之可證明y

#include<cstdio> typedef long long LL; void ex_gcd(LL a, LL b, LL &x, LL &y, LL &d){if (!b) {d = a, x = 1, y = 0;}else{ex_gcd(b, a % b, y, x, d);y -= x * (a / b);} } LL inv(LL t, LL p){//如果不存在,返回-1 LL d, x, y;ex_gcd(t, p, x, y, d);return d == 1 ? (x % p + p) % p : -1; } int main(){LL a, p;while(~scanf("%lld%lld", &a, &p)){printf("%lld\n", inv(a, p));} }

方法三:(當p為質數時,可以用下面的方法在O(n)的復雜度下求出多個數關于p的逆元)

當p是個質數的時候有
inv(a) = (p - p / a) * inv(p % a) % p
?

這為啥是對的咩?

證明不想看的孩子可以跳過。。。

證明:
設x = p % a,y = p / a
于是有 x + y * a = p
(x + y * a) % p = 0
移項得 x % p = (-y) * a % p
x * inv(a) % p = (-y) % p
inv(a) = (p - y) * inv(x) % p
于是 inv(a) = (p - p / a) * inv(p % a) % p
?

然后一直遞歸到1為止,因為1的逆元就是1

代碼:

#include<cstdio> typedef long long LL; LL inv(LL t, LL p) {//求t關于p的逆元,注意:t要小于p,最好傳參前先把t%p一下 return t == 1 ? 1 : (p - p / t) * inv(p % t, p) % p; } int main(){LL a, p;while(~scanf("%lld%lld", &a, &p)){printf("%lld\n", inv(a%p, p));} }

這個方法不限于求單個逆元,比前兩個好,它可以在O(n)的復雜度內算出n個數的逆元

遞歸就是上面的寫法,加一個記憶性遞歸,就可以了

遞推這么寫

#include<cstdio> const int N = 200000 + 5; const int MOD = (int)1e9 + 7; int inv[N]; int init(){inv[1] = 1;for(int i = 2; i < N; i ++){inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD;} } int main(){init(); }

練習 :? ZOJ3609? hdu1576? poj1601(拓展歐幾里得)?

總結

以上是生活随笔為你收集整理的逆元~(乘法逆元及其应用)的全部內容,希望文章能夠幫你解決所遇到的問題。

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