乘法逆元
来源:互联网 发布:淘宝托管软件是真的吗 编辑:程序博客网 时间:2024/06/05 16:17
一. 乘法逆元
1. 逆元
在群
2. 乘法逆元
在群
则称
为了方便表示,且下面的内容都只涉及到相同的
二. 逆元的性质
【性质1】(存在唯一性)
对于
证明:假设存在
则有
矛盾。
【性质2】(完全积性函数)
证明:
由【性质1】知
【性质3】
证明:见后面求逆元的方法(5)线性递推的推导。
【性质4】
证明:
又
三. 求乘法逆元
1. 问题
已知:
条件:
求:
2. 常见方法
(1)枚举法
【方法】从
【复杂度分析】
求单个数的逆元:
求
【代码】
#include <cstdio>int a,p;int main(void){ scanf("%d%d",&a,&p); for (int _a=1;_a<p;_a++) if (a*_a%p==1) {printf("inv[a]=%d\n",_a);return 0;}}
(2)快速幂
【方法】根据欧拉定理,
根据逆元的存在唯一性,
即可用快速幂求解。
【复杂度分析】
求单个数的逆元:
求
【代码】
#include <cstdio>int a,p;int Pow(int i,int j){ if (!j) return 1; int now=Pow(i,j>>1); now=now*now%p; if (j&1) now=now*i%p; return now;}int main(void){ scanf("%d%d",&a,&p); printf("%d\n",Pow(a,p-2)); return 0;}
(3)扩展欧几里得算法
【方法】
要使得
我们对
设当前我们的状态为
①当
②当
现在有
现在我们要构造
那么就可以使
最后的
【时间复杂度】
单个:
所有:
【代码】
#include <cstdio>int a,p;int x,y;void exgcd(int a,int b){ if (!b) {x=1,y=0;return;} exgcd(b,a%b); int _x=x,_y=y; x=_y,y=_y*(a/b)-_x; x%=p,y%=p;}int main(void){ scanf("%d%d",&a,&p); exgcd(a,p); printf("%d\n",(x+p)%p); return 0;}
(4)欧拉筛法
【方法】
注意这是积性函数!!!还是完全积性函数!!!
能不能用欧拉筛法求出所有的逆元!!!
①
好像没事么特别的办法,直接用前面的方法2和3来解决,
②
完全积性函数
甚至不用分有没有完全平方数因子的类。
【复杂度分析】
最初学习的时候,发现素数一次
但是某天突然想起有个叫做素数定理的东西。
记
那么求所有素数的复杂度为:
所有合数的复杂度为:
所以总的复杂度为
所以求所有逆元的时间复杂度为:
【代码】
#include <cstdio>const int N=100000;int p;int vis[N],pri[N];int inv[N];int mi(int i,int j){ if (!j) return 1; int now=mi(i,j>>1); now=now*now%p; if (j&1) now=now*i%p; return now;}int main(void){ scanf("%d",&p); vis[1]=1,inv[1]=1; for (int i=2;i<p;i++) { if (!vis[i]) pri[++pri[0]]=i,inv[i]=mi(i,p-2); for (int j=1;j<=pri[0];j++) { if (i*pri[j]>=p) break; inv[i*pri[j]]=inv[i]*inv[pri[j]]; if (i%pri[j]==0) break; } } for (int i=1;i<p;i++) printf("inv[%d] = %d\n",i,inv[i]); return 0;}
(5)线性递推
【方法】
考虑能不能直接线性递推。
考虑能不能从小到大递推。
①
②假设我们已经求出了
同余与整除、取模息息相关,又要利用起之前的结果。
不难想到取
现在可以利用的有
这样就可以线性递推了啊。
【复杂度分析】
求所有逆元的复杂度为
【代码】
#include <cstdio>const int N=10000;int p;int inv[N];int main(void){ scanf("%d",&p); inv[1]=1; for (int i=2;i<p;i++) inv[i]=(-(p/i)*inv[p%i]%p+p)%p; for (int i=1;i<p;i++) printf("inv[%d] = %d\n",i,inv[i]); return 0;}
3. 注意
(1)逆元的存在唯一?
注意,逆元的存在唯一性是在
如果
只有
(2)方法的比较
- 较简单的题,可以使用效率较低的方法1求逆元。
- 求少量数的逆元,或者模数很大,通常使用算法23。
- 求大量数的逆元,通常使用算法45。
个人推荐算法5,但是如果想不起的话可以写算法4。
四. 逆元的使用
原理:【性质4】
使用情况1:当我们要求
例题:【BZOJ】1004 Cards
使用情况2:当我们要求
这种方法好像目前没有考过,下次自己出一道2333。
- 乘法逆元
- 乘法逆元
- 关于乘法逆元
- 乘法逆元
- 乘法逆元
- 乘法逆元
- 求乘法逆元
- 求乘法逆元
- 乘法逆元
- 乘法逆元
- 乘法逆元
- 乘法逆元
- 乘法逆元
- 乘法逆元基础知识
- 乘法逆元
- 乘法逆元
- 乘法逆元
- 乘法逆元求法
- Python IDE(集成开发环境)汇总
- 很多网友都对流水灯感兴趣
- 【JSP页面表单提交,controller接收为乱码,以及保存到数据库时为乱码】解决方法
- 关于“世上只有妈妈好”的单片机音乐演奏程序
- 关于SM2的应用方法
- 乘法逆元
- 关于 BCD 码减数求补的问题
- C程序翻译成汇编语言
- 数据库索引的实现原理
- Socket 短连接、长连接
- 利用单片机的定时器中断,周期性输出矩形波
- 关于8279的实例
- 在7000H--700FH中查出“00”的个数
- perl json encode_json decode_json