逆元相关

快速幂求逆元

ll quickpow(ll base,ll power)
{
    ll ret=1;
    for(;power;power>>=1)
    {
        if(power&1)
        {
            ret=(ret*base)%mod;
        }
        base=(base*base)%mod;
    }
    return ret;
}
View Code

食用方法:quickpow(base,mod-2)

正确性:费马小定理

扩展欧几里得求逆元

ll exgcd(ll a,ll b,ll &x,ll &y)
{
    if(b==0)
    {
        x=1,y=0;
        return a;
    }
    else
    {
        ll ans=exgcd(b,a%b,x,y);
        ll temp=x;
        x=y;
        y=temp-a/b*y;
        return ans;
    }
}
View Code

(其实我是直接用的poj1061的代码的)

食用方法:a为所求数,x为逆元,b为模数,y为随便。

正确性:

我们设逆元为x

有ax=1(mod p)

ax+pk=1

求出求出x即可

首先 假如我们要求(a/b)mod p 我们只用求a*b^1 mod p即可

线性求所有逆元:

void inverse(int n)
{
    inv[1]=1;
    for(int i=2;i<=n;i++)
    {
        inv[i]=((mod-(mod/i))*(inv[mod%i]))%mod;
    }
}
View Code

食用方法:我不多说了

正确性:http://blog.miskcoo.com/2014/09/linear-find-all-invert

不过以上都不是重头 重头是这个:

http://blog.csdn.net/the301stdoub/article/details/47017773

假如我们知道了inv[n!],由于inv[(n-1)!]=inv[n!]*n 我们可以知道n-1的阶乘 因此我们可以线性求所有阶乘的逆元

void getfacinv(int n)
{
    fac[0]=1;
    for(int i=1;i<=n;i++)
    {
        fac[i]=(fac[i-1]*i)%mod;
    }
    inv[n]=quickpow(fac[n],mod-2)%mod;
    for(int i=n-1;i>=1;i--)
    {
        inv[n]=(inv[n+1]*(n+1))%mod;
    }
}
View Code

所以我想大家应该知道我想干啥了。

原文地址:https://www.cnblogs.com/redwind/p/6524729.html