乘法逆元(转)
定义:满足a*k≡1 (mod p)的k值就是a关于p的乘法逆元。
为什么要有乘法逆元呢?
当我们要求(a/b) mod p的值,且a很大,无法直接求得a/b的值时,我们就要用到乘法逆元。
我们可以通过求b关于p的乘法逆元k,将a乘上k再模p,即(a*k) mod p。其结果与(a/b) mod p等价。
证:
根据b*k≡1 (mod p)有b*k=p*x+1。
k=(p*x+1)/b。
把k代入(a*k) mod p,得:(a*(p*x+1)/b) mod p
=((a*p*x)/b+a/b) mod p
=[((a*p*x)/b) mod p +(a/b)] mod p
=[(p*(a*x)/b) mod p +(a/b)] mod p
//p*[(a*x)/b] mod p=0
所以原式等于:(a/b) mod p
1 #include<bits/stdc++.h> 2 using namespace std; 3 int a,P; 4 inline int exgcd(int a,int b,int &x,int &y){ 5 if(b==0){ 6 x=1; y=0; return a; 7 } 8 int ans=exgcd(b,a%b,x,y); 9 int tmp=x; x=y; 10 y=tmp-a/b*y; 11 return ans; 12 } 13 inline int niyuan(int a,int P){ 14 int x=0,y=0; 15 int gcd=exgcd(a,P,x,y); 16 if(x>0){ 17 for(int t=0;;t--){ 18 if((x+P/gcd*t)<=0) return x; 19 else x=x+P/gcd*t; 20 } 21 } 22 else{ 23 for(int t=0;;t++){ 24 if((x+P/gcd*t)>0){ 25 x=x+P/gcd*t; 26 return x; 27 } 28 } 29 } 30 } 31 int main(){ 32 scanf("%d%d",&a,&P); 33 printf("%d",niyuan(a,P)); 34 return 0; 35 }