求逆元的方法

扩展欧几里得求逆元

ax=1(mod p),a,p互质,那么原式可以写成ax+py=gcd(a,p)(mod p),a,p互质,所以gcd(a,p)=1,所以原式等于ax+py=1(mod p)
,直接通过扩展欧几里得算法即可轻松求得,如果不知道什么是扩展欧几里得算法,建议先学一下https://blog.csdn.net/TheWayForDream/article/details/109014990
代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll quik_pow(ll dishu , ll zhishu, ll mod)
{
	ll ans=1;
	while(zhishu)
	{
		if(zhishu&1)
		{
			zhishu--;
			ans=ans*dishu%mod;
		}
		else
		{
			zhishu>>=1;
			dishu=dishu*dishu%mod;
		}
	}
	return ans;
}
ll exgcd(ll &x,ll &y,ll &g,ll a,ll b)//g为gcd(a,b) 
{
	if(b==0)
	{
		x=1;
		y=0;
		g=a;
		return 0;
	} 
	exgcd(x,y,g,b,a%b);
	ll x1=y;
	ll y1=x-(a/b)*y;
	x=x1;
	y=y1;
	return 0;
}
int main()
{
	ll a,b;
	cin>>a>>b;
	ll x,y,g;
	exgcd(x,y,g,a,b);
	ll s=b/g;
	x=(x%s+s)%s;//a的逆元,这里是避免x出现负数 
	cout<<x;
	return 0; 
}

通过费马小定理求逆元

什么是费马小定理
定义:如果p是素数,那么a^(p-1)=1(mod p) ,所以我们令ax=1(mod p),那么x=a^(p-2),这里的x就是a逆元,直接用快速幂求得即可

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll quik_pow(ll dishu , ll zhishu, ll mod)
{
	ll ans=1;
	while(zhishu)
	{
		if(zhishu&1)
		{
			zhishu--;
			ans=ans*dishu%mod;
		}
		else
		{
			zhishu>>=1;
			dishu=dishu*dishu%mod;
		}
	}
	return ans;
}

int main()
{
	cin>>a>>p;
	ll ans=quik_pow(a,p-2,p);
}

线性求逆元

当题目要求你求某段区间的所有关于模p的逆元的时候,这个算法是非常快的
学习中,待完善,还请见谅

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值