求逆元

#include<bits/stdc++.h>
using namespace std;
//求逆元,方法是费马小定理,还有一种更快的线性算法
long long mod=1000000007L;
int pow_mod(int x,int y,int c){
    if(y==0) return 1;
    int q=pow_mod(x,y/2,c)%c;
    if(y&1) return (q*q*x)%c;
    else return (q*q)%c;
}
int ni1(int a,int b){
    //a%b的逆
    //已知费马小定理 a^(b-1)%b==1 b为素数
    //那么 a^(b-2)*a%b==1 ,所以 a mod b的逆是a(b-2)
    //因为求的是模几逆,肯定是,这样不容易溢出
    return pow_mod(a,b-2,b);
}
//当然如果,就直接调用pow_mod
//如果求一堆数的逆,有一个线性算法更快,根据递推式.png
int inv[10001],sum=1000;
void ni2(int p){
    inv[1]=1;
    for(int i=2;i<=sum;i++){
        inv[i]=(p-p/i)*inv[p%i]%p;
        cout<<i<<" de inv shi "<<inv[i]<<endl;
    }
}
//上式可用于阶乘求逆
// ine[i]=(mod-(mod/i)*ine[mod%i])%mod; i的逆
// jcc[i]=jcc[i-1]*ine[i]%mod; 阶乘的逆
//即ab的逆=a的逆*b的逆,因为模运算规律,乘法可加mod,而且逆也是一个数。

int main()
{
    cout<<ni1(2,5)<<endl;
    ni2(5);
    return 0;
}

 

posted @ 2020-06-06 21:35  西伯利亚挖土豆  阅读(332)  评论(0编辑  收藏  举报