乘法逆元超详解
目錄
一,模運算的性質
二,除法的模運算?
? ? ? ? 1.除法模運算
? ? ? ? 2.解決除法模運算問題
三,乘法逆元的性質
? ? ? ? ?1,乘法逆元總存在嗎?
? ? ? ? 2.什么時候一定存在乘法逆元
?三,求乘法逆元
? ? ? ? ?1.費馬小定理
? ? ? ? 1.1?C++ 由費馬小定理求乘法逆元(p為質數時)
輸入輸出樣例
????????2.擴展歐幾里得算法
? ? ? ? 2.1 求逆元代碼
? ? ? ? 3.線性求逆元
? ? ? ? 3.1 求逆元
3.乘法逆元應用
一,模運算的性質
? ? ??1.? (a+b)%p=(a%p+b%p)%p
? ? ? 2.? (a-b)%p=(a%p-b%p)%p
注意:(9-7)%8=(9%8-7%8)%8=-6 ;不是我們要的值,這時要加上p,改為:
? ? ? 3.? (a-b)%p=( (a%p-b%p) % p + p )%p
? ? ? 4.? (a*b)%p=((a%p)*(b%p))%p
二,除法的模運算?
? ? ? ? 1.除法模運算
? ? ? ? (a/b)%p=(a%p)/(b%p) ,如果我們保證可以整除,它是否成立呢?
取a=8,b=2,p=6; 左式=4,右式=1;也就是說?除法的模運算不一定成立。
? ? ? ? 2.解決除法模運算問題
????????能否將除法轉化為乘法?找到 binv ,使得 (a/b)%p==(a*binv)%p?;若能,則稱 binv 為 b在模p意義下?的乘法逆元 ;
三,乘法逆元的性質
? ? ? ? (1) 設 ( a / b )?x ( mod p) ; 即 (a / b ) %p=x % p ;
? ? ? ? (2) 設存在 b?,滿足 a*bx ( mod p)?
? ? ? ? (1)*b :? a??bx ( mod p) ……(3)
????????(2)*b :???a*b?*b ??bx?( mod p ) ……(4)
????????(4)-(3)?:? a*( b?*b -1? )??0 ( mod p ) ……(5)
? ? ? ? 因為我們在找b的乘法逆元,而 a 是任意的數 ,所以為了使 (5) 恒成立,則?( b?*b -1? )0
即?? b?* b 1 ( mod p); 此時?binv 就是?b在模p意義下?的乘法逆元 ;
? ? ? ? ?1,乘法逆元總存在嗎?
????????對于??b?* b 1 ( mod p),是否總存在 這樣的 b??
????????取 b=2,p=10 則 2 *?b1 ( mod 10) ,即不存在。
? ? ? ? 2.什么時候一定存在乘法逆元
? ? ? ? 若存在乘法逆元,則必滿足??b?* b 1 ( mod p);
則設?b?* b ?k*p + 1 ……(1);
設g為b,p的最大公約數,即 g = gcd ( b?, p )?……(2);
? ? 則 g*?b?* b ?g*k*p + 1 ……(3);
????????g(?b?* b-k*p)=1……(4) 我們是在整數范圍討論的,所以 (4)式成立當且僅當
????????g=1 &&???b?* b-k*p =1
?結論: 乘法逆元存在當且僅當 b與p互質
?三,求乘法逆元
? ? ? ? ?1.費馬小定理
? ? ? ? (1)……?b?* b 1 ( mod p)
? ? ? ? (2)……費馬小定理:若 p 為質數, 則 a1 ( mod p) ;
由 (2)得: a*a??1 ( mod p) ;
則 結合(1)有??b= b?滿足 (1)式;?
? ? ? ? 1.1?C++ 由費馬小定理求乘法逆元(p為質數時)
#include <iostream> using namespace std; typedef long long ll; ll fast_pow(ll a, ll b, ll p)//快數冪算法 {ll ans = 1;a %= p;while (b){if (b & 1){ans = (ans * a) % p;}a = (a * a) % p;b >>= 1;}return ans; }ll get_inv(ll x, ll p) {return fast_pow(x, p - 2, p); } int main() {ll x, p;cin >> x >> p;for (int i = 1; i <= x; i++){cout<<get_inv(i, p)<<endl;} }輸入格式:
一行n,p
輸出格式:
n行,第i行表示i在模p意義下的逆元。
輸入輸出樣例
輸入樣例#1:?
10 13輸出樣例#1:
1 7 9 10 8 11 2 5 3 4????????2.擴展歐幾里得算法
(1)擴展歐幾里得算法:求 ax+by=gcd(a,b)?……(1)的一組 x,y;
(2) 求a 在模 p 意義下的乘法逆元 :(這里改求 a 防止字符混淆)
? ? ? ????????????????a*a1 ( mod p )? ? ? ?……(2)
由(2) 得:?a*a+p*y=1 ……(3)
已知a , p 互質,即 gad(a,p)=1 ……(4)
(3),(4)得??a*a+p*y=gcd(a,b)=1 ,對照歐幾里得公式,得 不需要 p為質數,但要求 a , p互質,即乘法逆元存在即可。
? ? ? ? 2.1 求逆元代碼
#include <iostream> using namespace std; typedef long long ll; void exgcd(ll a, ll b, ll& x, ll& y){if (b == 0){x = 1;y = 0;return;}exgcd(b, a % b, y, x);y -= (a / b) * x; }ll get_inv(ll a, ll p) {ll x = 1, y = 0;exgcd(a, p, x, y);return (x % p + p) % p;//防止出現負數 } int main() {ll a, p;cin >> a >> p;for (int i = 1; i <= a; i++){cout<<get_inv(i, p)<<endl;} }? ? ? ? 3.線性求逆元
(1)求1~n 依次在模p意義下得逆元;
(2)題目保證 p 為質數, 且 p>n;
(3)上述兩種方法略慢,因為需要對每一個數求逆元
? ? ? ? (1)對于一個數。由于 p>x。設 p = kx + r, k =?, r = p % x ;
? ? ? ? (2)在模 p 的意義下:
kx + r??0 ( mod p )????kx??-r ( mod p )??k * r?* x??-1?? -x * x?( mod p )
? x*?? ?-x * x?( mod p )
r*k*x=?-x * x?( mod p )
x?-k * r? ( mod p )
?????????這里我們得到一個遞推式,如果知道 r?的值 ,我們就能得到 x?的值。
根據假設, r = p % x <x,因此我們如果依次求 1~n 的逆元,那么 r?一定比 x?先被求出。即求?x?時已經知道 r?的值。
注意到若按等式處理,滿足等式的 x?應為負數?不是的 ,我們做一下變化
?x?( -k * r? ( mod p ) + p ) % p?
? ? ? ? 3.1 求逆元
#include <iostream> using namespace std; typedef long long ll; const int MAXN = 2e5; int n, p; int inv[MAXN]; void niyuan(int n) {inv[1] = 1;for (int i = 2; i <= n; i++){inv[i] = -(p / i) * inv[p % i]; //x_inv= -k * r_inv ;inv[i] = (inv[i] % p + p) % p;} } void printNiyuan(int n) {for (int i = 1; i <= n; i++){cout << inv[i] << " ";} } int main() {cin >> n >> p;niyuan(n);printNiyuan(n);}3.乘法逆元應用
適用于很大的數的乘積,最后的值的 p取模輸出,例如求排列組合的個數
總結
- 上一篇: 路由器ddns php,路由器实现DDN
- 下一篇: 图片采集器-网页图片批量采集器免费