扩展欧几里得算法
2015-09-03 18:27
281 查看
1 欧几里得算法标准代码
这个代码算的是符合a * x + b * y = gcd(a, b)的一组x, y, 同时返回了gcd(a, b)
因为a * x1 + b * y1 = gcd(a, b)
gcd(a, b) = gcd(b, a % b)
那么a * x1 + b * y1 = gcd(b, a % b) = b * x2 + (a - a/b*b) * y2; // a % b = a - a/b*b;而且x2, y2是更内层的
把上面得到的式子变形得 a * x1 + b * y1 = a * y2 + b * (x2 - a / b * y2);
对应x1 = y2, y1 = x2 - a / b * y2;
里面一层有返回值的时候想着返回上一层就好理解了,比如对应x1 = y2, y1 = x2 - a / b * y2;可以理解为上一层的y2赋给这一层的x1,上一层的 x2 - a / b * y2赋给y1
2求 a * x + b * y = c的解
就是根据上面模板算出gcd(a, b)的同时算出a * x + b * y = gcd(a, b)的解,
然后x = x * c / gcd(a, b); y = y * c / gcd(a, b);
3 求逆元
这个算法好久之前就想搞定,今天终于搞定了,好开心啊
求a在mol b下的逆元, 即求满足a * x ≡ 1 (mod b)的x //要求a和b互质
套用扩展欧几里得模板,则苛求出来 满足 a * x + b * y = gcd(a, b)的x, 因为a,b互质,故gcd(a, b) = 1所求x即a在mod b情况下的逆元,
输出大于0且最小的答案,所以 x = (x % b + b) % b;
这个代码算的是符合a * x + b * y = gcd(a, b)的一组x, y, 同时返回了gcd(a, b)
因为a * x1 + b * y1 = gcd(a, b)
gcd(a, b) = gcd(b, a % b)
那么a * x1 + b * y1 = gcd(b, a % b) = b * x2 + (a - a/b*b) * y2; // a % b = a - a/b*b;而且x2, y2是更内层的
把上面得到的式子变形得 a * x1 + b * y1 = a * y2 + b * (x2 - a / b * y2);
对应x1 = y2, y1 = x2 - a / b * y2;
里面一层有返回值的时候想着返回上一层就好理解了,比如对应x1 = y2, y1 = x2 - a / b * y2;可以理解为上一层的y2赋给这一层的x1,上一层的 x2 - a / b * y2赋给y1
__int64 exGcd(__int64 a,__int64 b,__int64 &x,__int64 &y) { if(b==0){ x=1; y=0; return a; } __int64 g=exGcd(b,a%b,x,y); __int64 temp=x; x=y; y=temp-(a/b)*y; return g; }
2求 a * x + b * y = c的解
就是根据上面模板算出gcd(a, b)的同时算出a * x + b * y = gcd(a, b)的解,
然后x = x * c / gcd(a, b); y = y * c / gcd(a, b);
#include <cstdio>
__int64 exGcd(__int64 a,__int64 b,__int64 &x,__int64 &y) { if(b==0){ x=1; y=0; return a; } __int64 g=exGcd(b,a%b,x,y); __int64 temp=x; x=y; y=temp-(a/b)*y; return g; }
int main()
{
__int64 a, b, c, x, y, gc;
while(scanf("%I64d%I64d%I64d", &a, &b, &c) == 3)
{
gc = exGcd(a, b, x, y);
if(c % gc)
{
printf("无解\n");
continue;
}
else
printf("%I64d %I64d\n", x*c/gc, y*c/gc);
}
}
3 求逆元
这个算法好久之前就想搞定,今天终于搞定了,好开心啊
求a在mol b下的逆元, 即求满足a * x ≡ 1 (mod b)的x //要求a和b互质
套用扩展欧几里得模板,则苛求出来 满足 a * x + b * y = gcd(a, b)的x, 因为a,b互质,故gcd(a, b) = 1所求x即a在mod b情况下的逆元,
输出大于0且最小的答案,所以 x = (x % b + b) % b;
#include <iostream> using namespace std; void exgcd(int a, int b, int &x, int &y) { if(b==0) { x = 1; y = 0; return; } exgcd(b, a%b, x, y); int t = x; x = y; y = t - a/b*y; } int main() { int b,mod, x, y; while(cin>>b>>mod) { exgcd(b,mod, x, y); cout<<(x%mod+mod)%mod<<endl; } return 0; }
相关文章推荐
- C++基础---string类的operator==/operator!=/operator</operator<=/operator>/operator>=/compare
- GCJ 2008 Round1AA
- 组合数C(n,m)的计算
- C++函数中那些不可以被声明为虚函数的函数
- 2012-2013 ACM-ICPC, NEERC, Central Subregional Contest H Milestones1 (暴力)
- 框架模式MVP在Android中的使用
- 对加权(无负值边)的图进行最短路径搜索
- Win10系统“获取会员版本”选项不可用怎么办?“获取会员版本”选项不可用的解决方法
- C++基础---string类的operator=/assign
- myeclipse2014配置spring
- C语言中链表怎么删除结点?
- C语言中链表怎么删除结点?
- C++基础---string类的operator<</operator>>/getline
- android切割音视频
- Windows平台下搭建Git服务器
- 修改Mac系统自带Vim配色方案
- 在Closing事件中,将e.Cancle设置成true,则Windows无法关机和重启系统的解决办法
- 20款响应式bootstrap后台模板源码下载
- POJ 1364 - King(差分约束)
- 树中的最长路问题