【逆元】(inv)

推荐博客:https://blog.csdn.net/baidu_35643793/article/details/75268911

1.费马小定理

在是素数的情况下,对任意整数都有。 
如果无法被整除,则有可以在为素数的情况下求出一个数的逆元,即为逆元。

题目中的数据范围1<=x<=10^9,p=1000000007,p是素数;

所以x肯定就无法被p整除啊,所以最后就得出x的(p-2)次方为x的逆元。

时间复杂度为O(logn);

代码:

typedef long long ll;
const int mod=1e9+7;
ll qpow(ll a,ll b)
{
    if(b<0) return 0;
    ll ans=1;
    a%=mod;
    while(b)
    {
        if(b&1) ans=(ans*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    }
    return ans;
}
ll inv(ll a)
{
    return qpow(a,mod-2);
}

2.扩展欧几里得

代码:


ll extend_gcd(ll a, ll b, ll x, ll y) {
    if (b == 0) {
        x = 1, y = 0;
        return a;
    }
    else {
        ll r = extend_gcd(b, a % b, y, x);
        y -= x * (a / b);
        return r;
    }
}
ll inv(ll a, ll n) {
    ll x, y;
    extend_gcd(a, n, x, y);
    x = (x % n + n) % n;
    return x;

}

(3) 逆元线性筛 ( P为质数 )

求1,2,...,N关于P的逆元(P为质数)

复杂度:O(N)

代码:

const int mod = 1e9+7;
const int maxn = 10005;
int inv[maxn];
inv[1] = 1;
for(int i = 2; i < 10000; i++)
    inv[i] = inv[mod % i] * (mod - mod / i) % mod;

如果是求阶乘的逆元呢?(阶乘数组:fac[ ])

fac[0]=1;
for(ll i=1;i<=maxn;i++)
    fac[i]=(fac[i-1]*i)%mod;
inv[maxn]=mod_pow(fac[maxn],mod-2);
for(ll i=maxn-1;i>=0;i--)
    inv[i]=(inv[i+1]*(i+1))%mod;
发布了12 篇原创文章 · 获赞 0 · 访问量 339

猜你喜欢

转载自blog.csdn.net/Ramzes_666_fan/article/details/104198005
今日推荐