拓展欧几里得算法
来源:互联网 发布:阿里云服务器多台 编辑:程序博客网 时间:2024/06/05 02:32
昨天晚上睡前没事看书看到一个拓展欧几里得算法,感觉书上讲的有点简略, 盯着看了半天, 今天从网上搜了一下, 算是理解了一些。
废话不说, 直接用一个题来引入正题。HDU 1576
每组数据有两个数n(0 <= n < 9973)和B(1 <= B <= 10^9)。
21000 5387 123456789
79226060
题意可知 n = A % 9973 = A - A / 9973 * 9973;
设 x = A / B, 那么 A = Bx;
所以 n = Bx - A / 9973 * 9973;
这时候我设A / 9973 为y的话, n = Bx - 9973y;
现在我们只要解出x的值, 便可以得到 (A / B) % 9973的值, 这正是我们想要的。
喜闻乐见, 上面的我们的准备工作已经得到了一个和这个相似的式子, 上面的式子中nx1 = x, -ny1 = y.
n是已知的, 现在我们的目标就是解出x1 并乘以 n, 便能得到x的值!
这时候, 我们的拓展欧几里得算法上场了! 它的作用便是解决 Ax1 + By1 = gcd(A, B)问题!
设 int extgcd(int a, int b, int &x, int &y)为求解 Ax + By = gcd(A, B) 的函数, 于是我们可以递归的定义extgcd, 假设已经求到Bx' + (A % B)y' = gcd(A, B)的解x' , y', 将 A % B = A - A / B *B带入得到 Ay' + B(x' - (A / B ) * y') = gcd(A,B),联立Ax + By = gcd(A, B) , 显然当前递归深度的 x, y 和下一深度的x',y'的关系为 x = y', y = x' - (A/B) * y'。
递归边界为B = 0时, 显然gcd(A,B) = A,即 x = 1, y = 0.
这样, 我们就得到了代码。(部分摘自《挑战程序设计竞赛》(第二版))。
#include <bits/stdc++.h>using namespace std;int extgcd(int a, int b, int& x, int& y){ int d = a; if(b == 0) { x = 1; y = 0; } else { d = extgcd(b, a % b, x, y); int t = y; y = x - (a / b) * y; x = t; } return d;}int main(){ int t; scanf("%d", &t); int x, y; while(t--) { int n, b; scanf("%d%d", &n, &b); extgcd(b, 9973, x, y); if(x < 0) { x += 9973; } x = (x * n) % 9973; printf("%d\n", x); } return 0;}
- 欧几里得算法+拓展欧几里得算法
- 欧几里得算法&&拓展欧几里得算法
- 欧几里得算法&&拓展欧几里得算法
- 欧几里得与其拓展算法
- 拓展的欧几里得算法
- 拓展欧几里得算法
- 拓展欧几里得算法
- 拓展欧几里得算法模板
- 拓展的欧几里得算法
- 拓展欧几里得算法
- 拓展欧几里得算法
- 欧几里得拓展算法求模逆元
- 欧几里得算法及其拓展
- 拓展欧几里得算法
- 欧几里得算法及其拓展
- 拓展欧几里得算法详解
- 拓展欧几里得算法
- 拓展欧几里得算法
- SQL 分析函数累加
- 模拟ATM自动取款机功能
- input标签内容改变的触发事件
- 测试isEmpty null 方法
- 杀掉进程,静态广播接收器不再能接收到广播
- 拓展欧几里得算法
- java提高篇(八)-----实现多重继承
- Matlab并行计算
- sge安装
- CentOS安装JDK常用的三种方法
- 一天天
- 第3章 装配Bean---高级装配--笔记1
- angularJs功能实现简集
- iOS 布局篇(二) Masonry 使用与说明