扩展欧几里德算法计算乘法逆元详解
来源:互联网 发布:淘宝网图片保护入口 编辑:程序博客网 时间:2024/05/22 06:40
乘法逆元的定义:
A * X MOD N == 1则称X为A关于模N的乘法逆元。
注:
只有两个数互素的时候才会有乘法逆元。
两个数不互素是没有乘法逆元的。
费马小定理:
利用费马小定理只能求出N为素数的情况下的乘法逆元,所以还是需要采用扩展欧几里德算法来计算普遍情况下的乘法逆元的情况。
下面的算法是求出n的简化剩余集的元素个数,利用
an-1==1 MOD n
//n是素数,且a不能被n整除,且a与n互素才可以
int fai = 1;
for (int i = 2; i < n; i++)
{
if (gcd(i, n) == 1)
fai++;
}
cout<<(int)pow(a, fai - 1) %n;
扩展欧几里德算法:
N*X + A*Y == 1。
采用逆推的方式,首先利用欧几里德算法,求最大共因子到1,
N A
26 17
17 9
9 8
8 1
当A为1的时候,就到了需要逆推的时候,
定义x为递归的时候a的系数,y为b的系数
1 = 9 – 8 系数为x=1和 y=-9/8==-1
= 9 - (17 – 9 * 17/9) 除法为向下取整,系数为 x=-1=上一个的y
y=1-17/9*(-1)=2其中1为上一个的x,-1为上一层y
= ……直到结束
最后的y即为乘法逆元。
考虑特殊情况:
1. 当a>n的时候,例如5 * X MOD 3 == 1
此时需要将N加上A,计算5 * X MOD 8== 1
计算出乘法逆元后,y加上x即可。
5 3 =>3 2=>2 1
8 5=>5 3=>3 2=>2 1
最后计算的结果为8与5的系数,而结果需要的是5与3的系数,但是8=5+3,所以分解之后的结果为y+=x。
2. 当系数结果为负数的时候
如17 * X MOD 26 == 1,
最后Y == -3。显然乘法逆元不能为负数,且范围应为(1, N-1]之间的整数,所以需要将YMOD N即可,后在计算机内计算模余方法的缺陷,如果最后仍为负数,需要讲Y加上N。
-3+26 = 23。
利用等式加减17*26仍不变的性质。
3. 两个数不互素
输出没有乘法逆元即可。
运行结果:
代码 :
#include "iostream"using namespace std;//记gcd(a,b)表示非负整数a,b的最大公因数,那么:gcd(a,b)=gcd(b,a%b)int gcd(int a, int b){if (a < b){int temp = b;b = a;a = temp;}if (a%b == 0)return b;elsereturn gcd(b, a%b);}int ExtendEculid(int a, int b, int &x, int &y, int c){if (b == 1){x = 1;y = -c/a;return a;}int result = ExtendEculid(b, a%b, x, y, a);if (c != 0){int temp = x;x = y;y = temp - c / a*y;}return result;}//a*x+b*y=k,调用扩展欧几里德函数int Generate(int a, int b){int x, y;if (b > a){a += b;int result = ExtendEculid(a, b, x, y, 0);y += x;a -= b;}else{int result = ExtendEculid(a, b, x, y, 0);}y %= a;if (y < 0)return y + a;elsereturn y;}int main(){while (1){cout << "a * x mod n == 1\n请输入a:";int a, b;cin >> a;cout << "请输入n:";cin >> b;if (gcd(a, b) != 1)cout << "两个数不互素,没有乘法逆元!" << endl << endl;elsecout << "乘法逆元是" << Generate(b, a) << endl << endl;}}
- 扩展欧几里德算法计算乘法逆元详解
- 扩展欧几里德算法详解以及乘法逆元
- 欧几里德算法、扩展欧几里德算法、乘法逆元
- 扩展的欧几里德算法求乘法逆元
- 扩展欧几里德算法求乘法逆元(C语言版)
- 用扩展欧几里德算法来求乘法逆元(…
- 扩展的欧几里德算法求乘法逆元
- 扩展欧几里德与乘法逆元
- 扩展欧几里德定理--------乘法逆元
- 【数论】 欧几里德 扩展欧几里德 乘法逆元 挑战程序P115
- HDU 3923 polya+乘法逆元+扩展欧几里德
- ZOJ 3609 Modular Inverse(扩展欧几里德求乘法逆元)
- HDU 2669----Romantic(扩展欧几里德求乘法逆元)
- 51Nod 1256-乘法逆元(扩展欧几里德)
- 扩展欧几里德算法详解
- 扩展欧几里德算法详解
- 扩展欧几里德算法详解
- 扩展欧几里德算法详解
- android studio 2.3使用问题 Error: Not found; no service started
- 如何判断dll文件是32位的还是64位的?
- windows下安装redis方法总结
- python,关键词pass
- Class.forName()与ClassLoader.loadClass()的区别
- 扩展欧几里德算法计算乘法逆元详解
- 关于新手学习python最初可能会碰到的3个问题
- 【SysML】模块定义图(BDD, Block Definition Diagram)
- Visual Studio 2013出现错误LNK 2026(SAFESEH模块不兼容)如何解决
- C++内联和宏
- 折线分割平面
- this指针
- Visual Studio 2013 出现error C4996(fopen函数出错)如何解决
- CC2541蓝牙学习——ADC