zoukankan      html  css  js  c++  java
  • 逆元

    逆元定义
    逆元和我们平时所说的倒数是有一定的区别的,我们平时所说的倒数是指:a*(1/a) = 1,那么逆元和倒数之间的区别就是:假设x是a的逆元,那么 a * x = 1(mod p),也就是只多了一个取余的操作,这个取余的操作,就会保证a的逆元不一定只是a的倒数。那么我们的逆元有什么作用呢?

    并且取余还不满足下面式子:( a/b )%p = (a%p  /  b%p)  %  p ,那么我们如果遇到b过大必须在中间过程进行取余的操作,那么我们会发现在乘法中满足:(a*b) % p = (a%p  *  b%p) %p,那么我们只要将上面式子转换为下面乘法的式子就可以了

    我们用inv(b)来表示b的逆元,那么他一定满足:b*inv(b) = 1(mod p)    ==>  b = 1/inv(b) ,那么我们代入上面的除法的式子:(a/b)%p =     (a * inv(b)) %p = (a%p  *  inv(b)%p) % p

    这样我们就可以根据逆元来将除法取余的式子转换为乘法取余的式子

    下面看一下用快速幂求解逆元的算法

    首先听到这么高大上(主要是长)的名字,相信你的内心一定是崩溃的,仿佛见到了高斯定理或者欧拉定理一样(别着急啊,扩欧等下才讲) 
    但其实蒙哥马利快速模这个算法并没有那么高大上,它的局限性很大,只有在 p 是质数的情况下才可以使用 
    首先我们设 inv_a 是 a 的逆元 那么根据定义, inv_a * a ≡1 (mod p) 
    再根据 费马小定理 a^(p-1) ≡1 , 易得 inv_a * a ≡a^(p-1) (mod p) 
    移项,得: inv_a ≡ a^(p-2) 
    于是我们得到了快速幂模算法的一个前提条件: inv_a ≡ a^(p-2) (mod p)

    看代码:

    #include<iostream>
    using namespace std;
    typedef long long LL;
    const int mod=1e9+7;
    LL Quick_pow(LL a,LL n)
    {
        LL ans=1,res=a;
        while(n)
        {
            if(n&1) ans=ans*res%mod;
            res=res*res%mod;
            n>>=1;
        }
        return ans;
    }
    int main()
    {
        LL a;
        cin>>a;
        LL inv_a=Quick_pow(a,mod-2);
        cout<<inv_a<<endl;
        return 0;
    }
    当初的梦想实现了吗,事到如今只好放弃吗~
  • 相关阅读:
    ELF 格式简介
    gdb 使用说明;ARM 汇编
    博士研究生的组会PPT汇报相关-labgirls
    浅尝辄止·认识Blazor及基础使用
    VBA·Function的基础使用
    WCF·无法自动进入并单步执行服务器。调试器未能在服务器进程中停止。
    Word·查找任意汉字的方法
    VBA·编译错误:ByRef参数类型不符
    排坑·QQ浏览器打开MD文件时显示下载不能直接打开
    MSSQL·PIVOT关键字实现列转行
  • 原文地址:https://www.cnblogs.com/caijiaming/p/10561537.html
Copyright © 2011-2022 走看看