逆元讲解(三种方法)

本文详细介绍了同余的概念及主要性质,并通过实例说明了如何使用费马小定理和扩展欧几里得算法求解逆元。同时,还提供了一种线性求逆元的方法及其代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自:https://blog.youkuaiyun.com/LOOKQAQ/article/details/81282342

【同余的定义】:
 
【同余的主要性质】:
 
 (a+b)%d=(a%d+b%d)%d
 加减乘除都能分开写
 要注意的是减法,因为减法可能会减出来负值所以可以这样写(a-b+mod)%mod;
性质证明:
 

 

【逆元】
(1)定义:
 就是一个数的倒数,那为什么要求一个数的倒数:比如a/b这个时候b的值特别大,就是导致double精度不够所以我们要将a/b换成a*c,其中c^-1=b.

 

【费马小引理求解逆元】:(易知费马定理是有限制的:a与p要互质)
代码实现:(精华就是快速幂)
long long quickpow(long long a,long long b){
 if(b<0)  return 0;
 long long ret=1;
 a%=mod;
 while(b){
  if(b & 1 ) ret = ( ret *a ) % mod
  b>>=1;
  a = (a * a)% mod;
 }
 return ret;
}
long long inv(long long a){
 return quickpow(a,mod-2);
}
 
【扩展欧几里得算法求逆元】:

辗转相除法:

可以来这看看(回溯得到方程解):https://baike.baidu.com/item/辗转相除法/4625352?fr=aladdin#4

(2)扩展欧几里得算法的证明:
 
(3)求解逆元:
(4)代码实现:
int exgcd(int a,int b,int &x,int &y)
{
 if(b==0)
 { //推理,终止条件1
  x=1;
  y=0;
  return a;
 }
 int t=exgcd(b,a%b,x,y)
   int t=x;
   x=y;
   y=t-(a/b)*y;
   return r;  最大公约数
}
(3)、

但是对于要求好多数的逆元的题目,这样写会超时

我们还有线性求逆元的方法 

来看带余除法 式子 p=k*i+r 

我们可以写成 k*i+r≡0(mod p) 

式子两边同乘 i-1*r-1 (i-1,r-1皆为模p意义下的逆元) 

所以我们有 k*r-1+i-1≡0(mod p) 

i-1≡-k*r-1(mod p)

i-1≡-(p/i)*(p%i)-1(mod p)

这样我们就线性求得了逆元

代码:

#include <cctype>
#include <cstdio>
typedef long long LL;
const int MAXN=3000010;
int n,p;
LL inv[MAXN];
int hh() {
    scanf("%d%d",&n,&p);
    printf("1\n");
    inv[1]=1;
    for(int i=2;i<=n;++i) {
        inv[i]=(LL)(p-p/i)*inv[p%i]%p;
        printf("%d\n",inv[i]);
    }
    return 0;
}
int sb=hh();
int main(int argc,char**argv) {;}
线性求逆元
 

转载于:https://www.cnblogs.com/kongbursi-2292702937/p/10582258.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值