zoukankan      html  css  js  c++  java
  • 乘法逆元(转)

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

     

  • 相关阅读:
    Source Insight技巧收集
    宝贝,祝你生日快乐!
    【转载】C++中的extern C
    Meego
    source insight增加新类型方法
    点操作符和箭头操作符的异同
    【转载】mtk编译命令
    margin和padding的用法与区别以及bug处理方式
    js数组
    随机验证码,颜色同时刷新
  • 原文地址:https://www.cnblogs.com/CXCXCXC/p/5221748.html
Copyright © 2011-2022 走看看