逆元详解
来源:互联网 发布:梁溪淘宝 编辑:程序博客网 时间:2024/06/16 04:50
数论逆元是指 a*x = 1 (mod m) x为最小的整数
第一种,费马小定理,要求m为素数
用快速幂求pow(a,m-2) (mod m)
int power(int a,int b){ int ans = 1; a %= m; while(b){ if(b&1) ans = ans * a % m; b >>= 1; a = a * a % m; } return ans;}
第二种,用拓展gcd,要求a与m互质
ax + my = 1 (gcd(a,m) = 1),求解的x即为a关于m的逆元
int e_gcd(int a,int b,int& x,int& y){ if (b == 0) {x = 1;y = 0;return a;} else{ int d = e_gcd(b, a % b, y, x); y -= x * (a / b); return d; }}
第三种,m为奇质数(所以m=2不满足),O(n)求n个数的逆元
inv[i] = (m-m/i)*inv[m%i]%m
证明:
设 t=m/i,k=m%i则 t*i+k=0 (mod m)同除i t+k*inv[i] = 0 (mod m)移项 inv[i]*k = m-t (mod m) 同除k inv[i] = (m-t)*inv[k] (mod m)代入 inv[i] = (m-m/i)*inv[m%i]%m
递推代码
#include<cstdio>const int N = 200000 + 5;const int MOD = (int)1e9 + 7;int inv[N];int init(){ inv[1] = 1; for(int i = 2; i < N; i ++){ inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD; }}int main(){ init();}
递归代码
#include<cstdio>typedef long long LL;LL inv(LL t, LL p) {//求t关于p的逆元,注意:t要小于p,最好传参前先把t%p一下 return t == 1 ? 1 : (p - p / t) * inv(p % t, p) % p;}int main(){ LL a, p; while(~scanf("%lld%lld", &a, &p)){ printf("%lld\n", inv(a%p, p)); }}
阅读全文
0 0
- 逆元详解
- 逆元详解
- 逆元详解
- 逆元详解
- 逆元详解
- 逆元详解
- 详解--乘法逆元
- 逆元详解
- 逆元详解
- 逆元详解 求逆元的方法汇总
- 三种求乘法逆元方法详解
- 详解C++友元
- c++友元详解
- 享元模式详解
- 友元详解
- c++友元详解
- 友元详解
- [c++] 友元详解
- 用堆栈实现任意制度的转化
- JQuery动态添加表格tr td
- 通用二进制方式安装mariadb
- [AHOI2009]中国象棋
- Jenkins教程
- 逆元详解
- Session
- 虚拟机、虚拟驱动、镜像
- easy-ui静态页面样式加载延迟问题
- Python 数据类型转换
- 3.HotSpot虚拟机对象管理
- Spring Boot+Mybatis+Pagehelper分页
- VC++制作安装包
- web前端之滚动条事件