乘法逆元的计算方法

利用费马小定理

如果p为质数,gcd(a,p)=1,那么a^(p-1) ≡1 (mod p) 
则a^(p-2) ≡1/a (mod p) 
a^(p-2) ≡ inv(a) (mod p) 
inv(a) = a^(p-2) (mod p) 
其中时间复杂度为O(logn)

注意:模数 mod必须为质数才可以利用费马小定理求解

typedef long long ll;
ll quick_pow(ll a, ll b, ll yu)
{
	ll ans = 1;
	a = a % yu;
	while (b)
	{
		if (b & 1)
			ans = ans * a%yu;
		a = a * a%yu;
		b >>= 1;
	}
	return ans;
}    
ll inv(ll num)
{
    return quick_pow(a,mod - 2,mod)
}

利用扩展欧几里得

由公式a∗x+b∗y=gcd(a,b) 。 
若a,b互质且有解,则有a∗x+b∗y=1。 
当我们要求a关于b的逆元,我们可以这样看。 
a*x % b + b*y % b = 1 % b 
a*x % b = 1 % b 
a*x = 1 (mod b) 
可见,扩展欧几里德算法可以实现逆元。

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;
}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值