乘法逆元

对于缩系中的元素,每个数a均有唯一的与之对应的乘法逆元x,使得ax≡1(mod n)
一个数有逆元的充分必要条件是gcd(a,n)=1,此时逆元唯一存在 
逆元的含义:模n意义下,1个数a如果有逆元x,那么除以a相当于乘以x。

下面给出求逆元的几种方法:

1.扩展欧几里得

给定模数m,求a的逆相当于求解ax=1(mod m)
这个方程可以转化为ax-my=1 
然后套用求二元一次方程的方法,用扩展欧几里得算法求得一组x0,y0和gcd 
检查gcd是否为1 
gcd不为1则说明逆元不存在 
若为1,则调整x0到0~m-1的范围中即可

PS:这种算法效率较高,常数较小,时间复杂度为O(ln n)

2.费马小定理

在模为素数p的情况下,有费马小定理 
a^(p-1)=1(mod p) 
那么a^(p-2)=a^-1(mod p) 
也就是说a的逆元为a^(p-2)

而在模不为素数p的情况下,有欧拉定理 
a^phi(m)=1(mod m) (a⊥m) 
同理a^-1=a^(phi(m)-1)

因此逆元x便可以套用快速幂求得了x=a^(phi(m)-1)

但是似乎还有个问题?如何判断a是否有逆元呢?

检验逆元的性质,看求出的幂值x与a相乘是否为1即可

PS:这种算法复杂度为O(log2N)在几次测试中,常数似乎较上种方法大

当p比较大的时候需要用快速幂求解

当模p不是素数的时候需要用到欧拉定理

a^phi(p)≡1               (mod p)

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

a^(-1)≡a^(phi(p)-1)  (mod p)

所以
时间复杂度即求出单个欧拉函数的值

(当p为素数的时候phi(p)=p-1,则phi(p)-1=p-2可以看出欧拉定理是费马小定理的推广)

PS:这里就贴出欧拉定理的板子,很少会用欧拉定理求逆元

3.特殊情况

一:

当N是质数, 
这点也很好理解。当N是质数,0 < a < N时,,则a肯定存在逆元。 
而解出的就满足,故它是a的逆元。

在CF 696C,

求解就灰常方便了…

二:

求逆元一般公式(条件b|a)

ans=a/bmodm=amod(mb)/b

公式证明:

PS:实际上a mod (bm)/b这种的对于所有的都适用,不区分互不互素,而费马小定理和扩展欧几里得算法求逆元是有局限性的,它们都会要求互素,如果a与m不互素,那就没有逆元,这个时候需要a mod (bm)/b来搞(此时就不是逆元的概念了)。但是当a与m互素的时候,bm可能会很大,不适合套这个一般公式,所以大部分时候还是用逆元来搞

4.逆元打表

有时会遇到这样一种问题,在模质数p下,求1~n逆元 n< p(这里为奇质数)。可以O(n)求出所有逆元,有一个递推式如下

它的推导过程如下,设,那么

对上式两边同时除,进一步得到

再把替换掉,最终得到

初始化,这样就可以通过递推法求出1->n模奇素数的所有逆元了。

另外有个结论的所有逆元值对应中所有的数,比如,那么对应的逆元是

typedef  long long ll;
const int N = 1e5 + 5;
int inv[N];void inverse(int n, int p) {inv[1] = 1;for (int i=2; i<=n; ++i) {inv[i] = (ll) (p - p / i) * inv[p%i] % p;}
}
转自:https://blog.csdn.net/guhaiteng/article/details/52123385

更多例题:https://blog.csdn.net/acdreamers/article/details/8220787

线性求逆元   题目

ll c(int r,int l) {if (r<l) return 0;return jie[r]*inv[l]%mod*inv[r-l]%mod;
}
int main()
{jie[1] = 1;jie[0] = 1;inv[1] = 1;inv[0] = 1;for(int i = 2; i<=MAX-1; i++) jie[i] = (jie[i-1] * i)%mod;for(int i = 2; i<=MAX-1; i++) {inv[i] = (mod - mod/i*inv[mod%i]%mod)%mod;}
//这两个求逆元的公式都可以使用
//  for (int i=2; i<MAX; i++) {
//      inv[i]=inv[mod%i]*(mod-mod/i)%mod;
//  }
//预处理逆元的前缀积for (int i=2; i<MAX; i++) inv[i]=inv[i-1]*inv[i]% mod;

线性求逆元  题目

const ll mod = 1000000000+7;
const ll N = 300000+5;
const ll M = 3e5+3;
int n;
ll fac[1000005];            //阶乘
ll inv_of_fac[1000005];        //阶乘的逆元
int a[15];
ll dp[150][12];
ll qpow(ll x,ll n)
{ll ret=1;for(; n; n>>=1){if(n&1) ret=ret*x%mod;x=x*x%mod;}return ret;
}
void init()
{fac[1]=1;for(int i=2; i<=M; i++)fac[i]=fac[i-1]*i%mod;inv_of_fac[M]=qpow(fac[M],mod-2);for(int i=M-1; i>=0; i--)inv_of_fac[i]=inv_of_fac[i+1]*(i+1)%mod;//inv_of_fac[i]=qpow(fac[i],mod-2);//为什么不行啊 //也行
}
ll C(ll a,ll b)
{if(b>a) return 0;if(b==0) return 1;return fac[a]*inv_of_fac[b]%mod*inv_of_fac[a-b]%mod;
}

咖啡鸡的求逆元:

#include<bits/stdc++.h>
using namespace std;
const int maxn=4005;
const int E=2000;
typedef long long ll;
const ll M=1000000007;
ll f[maxn],nf[maxn],inv[maxn],dp[2][maxn];
int n,m;
ll C(ll x,ll y){return f[x]*nf[y]%M*nf[x-y]%M;
}
ll K(ll x){return C(x*2,x)*inv[x+1]%M;
}
void add(ll &x,ll y){x+=y; if (x>=M) x-=M;
}
int main(){inv[1]=1; for (int i=2;i<maxn;i++) inv[i]=M-(M/i)*inv[M%i]%M;f[0]=nf[0]=1; for (int i=1;i<maxn;i++) f[i]=f[i-1]*i%M,nf[i]=nf[i-1]*inv[i]%M;return 0;
}

无数种求逆元的方法总结相关推荐

  1. Matlab两种求相位的方法

    在matlab中有两种求相位方法. 1.使用phase函数. 比如a = 1+j*2 phase(a),则可以就a的相位.这个函数取实部为x轴,虚部为y轴. 2.使用函数atan2. atan2(y, ...

  2. C++丨常见的四种求最大公约数方法!赶紧收藏!

    为了更好的了解算法的概念,今天会分享一些C++求最大公约数几种常见的算法. 第一种:穷举法之一 穷举法,也叫枚举法,求最大公约数时从两者中较小的数开始,由大到小列举,直到找到第一个公约数为止. 解释: ...

  3. 不相交轮换的乘积怎么求_浅谈两种求条件极值的方法

    大家好,我是槿灵兮! 好久没发文了呢,高联考砸之后一直忙于高考复习,这次假期难得有点时间写点东东~ 看到专栏上面一位初二大佬 @一只柠檬精 写了这篇文章,原本我也有一个想写这文章的想法.索性就当此文是 ...

  4. 整数n分解成素数乘积c语言,关于几种求素数的方法(C语言描述)

    求出3到50w范围内所有的素数. 这类问题在C语言题目中经常会遇见.同样,大素数的研究对于密码学也起到了重要的作用.那么对于C语言的初学者,该如何编写程序计算素数呢? 1. 首先从素数的定义来看,&q ...

  5. 几种求CRC-CCITT的方法 [C/C#]

    // 所有原创文章转载请注明作者及链接 // blackboycpp(AT)gmail.com // QQ群: 135202158 方法1:将存有数据的字节数组进行逐位计算,求得字节形式的CRC vo ...

  6. 几种求最小公倍数的方法

    http://blog.csdn.net/iwm_next/article/details/7450424  这是原链接 谢谢该博主的分享,写的很不错哦.

  7. 常见三种求素数的方法

    #include<bits/stdc++.h> using namespace std; const int N = 100001; bool st[N]; int prime[N],cn ...

  8. 【数论】求逆元的四种方法

    逆元的定义 给定正整数a,p,如果有 ,且a与p互质,则称x的最小正整数解为a模p的逆元. 一.扩展欧几里得算法 使用条件:基本上通用,不要求p为质数,且效率高,时间复杂度为. 证明过程:有解的条件是 ...

  9. 取模除法(逆元)(费马小定理)(线性求逆元)

    文章目录 引言 逆元 费马小定理 内容 应用 证明 线性求逆元 thanks for reading! 引言 我们做题时经常会由于答案过大,被要求使答案对一个质数取模 我们都知道,加和乘对取模是没有影 ...

最新文章

  1. RabbitMQ是什么
  2. RxJava 源码解析之观察者模式
  3. HDU2045 不容易系列之(3)—— LELE的RPG难题(递推)
  4. javaweb利用struts2完成批量删除记录
  5. Qt 中 QXml/QDom*** api设计吐槽
  6. 如何通过Restful API的方式读取SAP Commerce Cloud的Product Reference
  7. c/c++ 重载运算符 函数调用运算符
  8. 前端基础进阶(十):面向对象实战之封装拖拽对象
  9. 23装饰模式(Decorator Pattern)
  10. 【牛客 - 368B】选点(dfs序,LIS 或 dfs序 + 树状数组 + 离散化,树状数组求LIS的方法)
  11. mysql相交_PHP-Mysql相交结果
  12. Storm与Spark区别
  13. Specify 的含义 ------ 转载
  14. 刷掉985/211,年底我却收到字节50W测试开发offer,实名揭露用人标准
  15. 打不开malloc和free函数
  16. 安装Spyder IDE
  17. 几种短距离无线通信技术及未来展望
  18. R720重装系统\WEPE装系统\WEPE
  19. java处理环比增长率
  20. 美国这100年来一共发生了多少次金融危机

热门文章

  1. [Leetcode][第201题][JAVA][数字范围按位与][位运算][Brian Kernighan]
  2. [剑指offer][JAVA]面试题第[31]题[栈的压入、弹出序列][栈]
  3. java运行时读取注解_Java自定义注解和运行时靠反射获取注解
  4. 怎么恢复oracle的包,【学习笔记】使用dbms_backup_restore包恢复数据库
  5. python能开发什么产品_三周学 Python ?不,三周做个产品
  6. nginx管理面板_吸塑包装自建网站上线,阿里云ecs+bt面板+WordPress
  7. Linux fwrite 什么时候刷新,linux的fwrite()使用方法,当前时间写入文本的程序
  8. ASCII,Unicode和UTF-8
  9. matlab sort descend,详解Matlab中 sort 函数用法
  10. 【转】GitHub 从单机到联机:玩转 Pull Request