乘法逆元(转)

  定义:满足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 }

 

 

 

posted @ 2016-02-26 20:44  CXCXCXC  阅读(1096)  评论(0编辑  收藏  举报