三种求逆元总结(模板)

逆元定义:方程ax≡1(mod  p),的解称为a关于模p的逆,当gcd(a,p)==1(即a,p互质)时,方程有唯一解,否则无解。

一.扩展欧几里得求解

证明如下:

a*x + b*y = 1

如果ab互质,才有解

这个解的x就是a关于b的逆元

y就是b关于a的逆元

为什么呢?

两边同时求余b

a*x % b + b*y % b = 1 % b

a*x % b = 1 % b

a*x = 1 (mod b)

所以x是a关于b的逆元

反之可证明y

条件: a,p互质才能使用


#include<cstdio>
typedef long long LL;
void ex_gcd(LL a, LL b, LL &x, LL &y, LL &d){
    if (!b) {d = a, x = 1, y = 0;}
    else{
        ex_gcd(b, a % b, y, x, d);
        y -= x * (a / b);
    }
}
LL inv(LL t, LL p)
{//如果不存在,返回-1 
    LL d, x, y;
    ex_gcd(t, p, x, y, d);
    return d == 1 ? (x % p + p) % p : -1;
}
int main(){
    LL a, p;
    while(~scanf("%lld%lld", &a, &p)){
        printf("%lld\n", inv(a, p));
    }
}

 

二.费马小定律求逆元

证明如下:

费马小定律:假如p是质数,且gcd(a,p)=1,那么 a^(p-1)≡1(mod p)

由费马小定律我们可以想到是不是很像逆元的形式,即:

a*a^(p-2)≡1(mod p)

也就是说a^(p-2)是a的逆元。

条件:p是质数,且a不能被p整除!!(费马小定律成立条件),复杂度O(log2(p))

#include<bits/stdc++.h>
#define ll long long
using namespace std;
//前提条件 p是质数,a不能被p整除 
ll power_mod(ll a, ll b, ll mod)
{
    ll ans = 1;
    while (b)
    {
        if (b & 1) ans = ans * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return ans;
}
int main(){
    ll a, p;
    while(~scanf("%lld%lld", &a, &p))
	{
		if(a%p==0) 
		printf("-1\n");
		else
        printf("%lld\n", power_mod(a,p-2,p));
    }
}

三.费马小定律扩展(用欧拉定律求逆元)

当p不是质数时就不能使用费马小定律了。

欧拉定律:若n,a为正整数,且n,a互质,则

其中φ(n)表示1~n中与n互质的数按顺序排布:x1,x2……xφ(n) (显然,共有φ(n)个数)

其实就是求出φ(p)后,与前面费马小定律的步骤一模一样。

 

条件:n,a为正整数,且n,a互质

四.用一般方法

注意这种方法不是用来求逆元的,而是用来化简(a/b)%p的

先介绍一下结论

证明

 

 

 

  • 7
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值