扩展欧几里德算法
2015-08-19 11:44
363 查看
void gcd(int a,int b,int &d,int &x,int &y) { if(!b) { d=a; x=1; y=0; } else { gcd(b,a%b,d,y,x); y-=x*(a/b); } }
扩展欧几里德算法的应用主要有以下三方面:
(1)求解不定方程;
(2)求解模线性方程(线性同余方程);
(3)求解模的逆元;
(1)使用扩展欧几里德算法解决不定方程的办法:
对于不定整数方程pa+qb=c,若 c mod Gcd(p, q)=0,则该方程存在整数解,否则不存在整数解。
上面已经列出找一个整数解的方法,在找到p * a+q * b = Gcd(p, q)的一组解p0,q0后,p * a+q * b = Gcd(p, q)的其他整数解满足:
p = p0 + b/Gcd(p, q) * t
q = q0 - a/Gcd(p, q) * t(其中t为任意整数)
至于pa+qb=c的整数解,只需将p * a+q * b = Gcd(p, q)的每个解乘上 c/Gcd(p, q) 即可。
在找到p * a+q * b = Gcd(a, b)的一组解p0,q0后,应该是得到p * a+q * b = c的一组解p1 = p0*(c/Gcd(a,b)),q1 = q0*(c/Gcd(a,b)),
p * a+q * b = c的其他整数解满足:
p = p1 + b/Gcd(a, b) * t
q = q1 - a/Gcd(a, b) * t(其中t为任意整数)
p 、q就是p * a+q * b = c的所有整数解。
用扩展欧几里得算法解不定方程ax+by=c;
bool judge(int a,int b,int c,int &x,int &y) { int d=gcd(a,b,x,y); if(c%d) return false; int k=c/d; x*=k; y*=k; //求得的只是其中一组解 return true; }
(2)用扩展欧几里德算法求解模线性方程的方法:
同余方程 ax≡b (mod n)对于未知数 x 有解,当且仅当 gcd(a,n) | b。且方程有解时,方程有 gcd(a,n) 个解。
求解方程 ax≡b (mod n) 相当于求解方程 ax+ ny= b, (x, y为整数)
设 d= gcd(a,n),假如整数 x 和 y,满足 d= ax+ ny(用扩展欧几里德得出)。如果 d| b,则方程
a* x0+ n* y0= d, 方程两边乘以 b/ d,(因为 d|b,所以能够整除),得到 a* x0* b/ d+ n* y0* b/ d= b。
所以 x= x0* b/ d,y= y0* b/ d 为 ax+ ny= b 的一个解,所以 x= x0* b/ d 为 ax= b (mod n ) 的解。
ax≡b (mod n)的一个解为 x0= x* (b/ d ) mod n,且方程的 d 个解分别为 xi= (x0+ i* (n/ d ))mod n {i= 0... d-1}。
设ans=x*(b/d),s=n/d;
方程ax≡b (mod n)的最小整数解为:(ans%s+s)%s;
a*dx就是a的倍数,同时也是n的倍数,即a*dx是a 和 n的公倍数.为了求出dx,我们应该求出a 和 n的最小公倍数,此时对应的dx是最小的.
设a 和 n的最大公约数为d,那么a 和 n 的最小公倍数为(a*n)/d.
即a*dx = a*n/d;
所以dx = n/d.
因此解之间的间隔就求出来了.
bool modular_linear_equation(int a,int b,int n) { int x,y,x0,i; int d=gcd(a,n,x,y); if(b%d) return false; x0=x*(b/d)%n; //特解 for(i=1;i<d;i++) printf("%d\n",(x0+i*(n/d))%n); return true; }
(3)用欧几里德算法求模的逆元:
同余方程ax≡b (mod n),如果 gcd(a,n)== 1,则方程只有唯一解。
在这种情况下,如果 b== 1,同余方程就是 ax=1 (mod n ),gcd(a,n)= 1。
这时称求出的 x 为 a 的对模 n 乘法的逆元。
对于同余方程 ax= 1(mod n ), gcd(a,n)= 1 的求解就是求解方程
ax+ ny= 1,x, y 为整数。这个可用扩展欧几里德算法求出,原同余方程的唯一解就是用扩展欧几里德算法得出的 x 。
相关文章推荐
- SET-MAP现代诗一首
- Netty4之Future/Promise异步模型
- new HashMap 发生了什么事情?
- android最全面试题71道题 详解
- Activity的onPause()官方文档翻译
- 如何优化C/C++语言代码(程序员必读)
- JVM内存参数详解以及配置调优
- maven的webapp产品热销部署eclipse,biz和其他子项目jar一揽子的解决方案无法找到!
- 用jsmooth + inno生成exe并制作简单安装包
- Add a dependency in Android Studio
- Ehcache RIM
- puppet进阶指南——exec资源详解
- puppet进阶指南——exec资源详解
- 10 个最受欢迎的 Java 开发的 CMS 系统
- 用SqlBulkCopy将数据复制到有自增字段的表中怎么办?结果的顺序不对怎么办?
- USACO 2008 Dec Silver 1.Hay For Sale
- 9012,9013三极管总结
- 网络测试Ping命令
- iOS文件操作NSFileManager和NSFileHandle
- android优化(二)---App调试内存泄露之图片Bitmap篇