/*==================================================*\
| GCD 最大公约数
\*==================================================*/
int gcd(int x, int y)
{ if (!x || !y) return x > y ? x : y; for (int t; t = x % y; x = y, y = t); return y;
}
/*==================================================*\
| 快速 GCD
\*==================================================*/
int kgcd(int a, int b)
{ if (a == 0) return b; if (b == 0) return a; if (!(a & 1) && !(b & 1)) return kgcd(a>>1, b>>1)<<1;else if (!(b & 1))return kgcd(a, b>>1); else if (!(a & 1)) return kgcd(a>>1, b); else return kgcd(abs(a - b), min(a, b));
}
/*==================================================*\
| 扩展 GCD
| 求x, y使得gcd(a, b) = a * x + b * y;
\*==================================================*/
int extgcd(int a, int b, int & x, int & y)
{ if (b == 0) { x=1; y=0; return a; } int d = extgcd(b, a % b, x, y); int t = x; x = y; y = t - a / b * y; return d;
} 

欧几里得算法

欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数。其计算原理依赖于下面的定理:

定理:gcd(a,b) = gcd(b,a mod b)
证明:a可以表示成a = kb + r,则r = a mod b
假设d是a,b的一个公约数,则有
d|a, d|b,而r = a – kb,因此d|r
因此d是(b,a mod b)的公约数
假设d 是(b,a mod b)的公约数,则
d | b , d |r ,但是a = kb +r
因此d也是(a,b)的公约数
因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,得证.

扩展欧几里德算法

扩展欧几里德算法是用来在已知a, b求解一组p,q使得p * a+q * b = Gcd(a, b) (解一定存在,根据数论中的相关定理)。扩展欧几里德常用在求解模线性方程及方程组中。下面是一个使用C++的实现:

int exGcd(int a, int b, int &x, int &y)
{if(b == 0){x = 1;y = 0;return a;}int r = exGcd(b, a % b, x, y);int t = x;x = y;y = t – a / b * y;return r;
}

把这个实现和Gcd的递归实现相比,发现多了下面的x,y赋值过程,这就是扩展欧几里德算法的精髓。
可以这样思考:
对于a’ = b, b’ = a % b 而言,我们求得 x, y使得 a’x + b’y = Gcd(a’, b’)
由于b’ = a % b = a – a / b * b (注:这里的/是程序设计语言中的除法)
那么可以得到:
a’x + b’y = Gcd(a’, b’) ==>
bx + (a – a / b * b)y = Gcd(a’, b’) = Gcd(a, b) ==>
ay +b(x – a / b*y) = Gcd(a, b)
因此对于a和b而言,他们的相对应的p,q分别是 y和(x-a/b*y)
补充:关于使用扩展欧几里德算法解决不定方程的办法
对于不定整数方程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) 即可

#include <iostream>
using namespace std;
//int gcd(int a, int b); //两个数的最大公约数
//int ngcd(int *pa, int n) //N个数的最大公约数
//int lcm(int a, int b) //两个数的最小公倍数
//int nlcm(int *pa, int n) //N个数的最小公倍数   int gcd (int a,int b)
{   if (b==0)   return a;   return gcd(b,a%b);
}   int ngcd(int *pa, int n)
{   if(n == 1)   return *pa;   return (gcd(pa[n-1], ngcd(pa, n-1)));
}   int lcm(int a, int b) //最小公倍数 = 两数乘积 / 最大公约数
{   return a*b/gcd(a, b);
}   int nlcm(int *pa, int n)
{   if(n == 1)   return *pa;   return lcm(pa[n-1], nlcm(pa, n-1));
}   int main()
{   int a,b,n,rgcd,rlcm,rngcd,rnlcm;   int pa[10];   printf("please input tow number:");   scanf("%d %d",&a,&b);   rgcd=gcd(a,b);   rlcm=lcm(a,b);   printf("最大公约数是:%d\n",rgcd);   printf("最小公倍数是:%d\n",rlcm);   printf("please input the n:");   scanf("%d",&n);   for (int i=0;i<n;i++)   scanf("%d",&pa[i]);   rngcd=ngcd(pa,n);   rnlcm=nlcm(pa,n);   printf("最大公约数是:%d\n",rngcd);   printf("最小公倍数是:%d\n",rnlcm);   return 0;
}

GCD,快速GCD,扩展GCD相关推荐

  1. POJ-2065 SETI 高斯消元,扩展GCD

    该题题义是给定如下一个方程组: F(1) = C1 (mod) P F(2) = C2 (mod) P F(3) = C3 (mod) P ... 其中F(1) = A(1,1)*x1 + A(1, ...

  2. 模板—扩展GCD*2

    有必要重新学一下扩展GCD emmmm. 主要是扩展GCD求解线性同余方程$ax≡b (mod p)$. 1.方程有解的充分必要条件:b%gcd(a,p)=0. 证明: $ax-py=b$ 由于求解整 ...

  3. 扩展gcd codevs 1200 同余方程

    codevs 1200 同余方程 2012年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题目描述 Description 求关 ...

  4. UESTC 288 青蛙的约会 扩展GCD

    设两只青蛙跳了t步,则此时A的坐标:x+mt,B的坐标:y+nt.要使的他们在同一点,则要满足: x+mt - (y+nt) = kL (p是整数) 化成: (n-m)t + kL = x-y (L ...

  5. GCD及其扩展GCD详解

    转自:http://www.cnblogs.com/yuelingzhi/archive/2011/08/13/2137582.html 扩展欧几里德算法-求解不定方程,线性同余方程. 设过s步后两青 ...

  6. POJ 1061 青蛙的约会(扩展GCD求模线性方程)

    题目地址:POJ 1061 扩展GCD好难懂..看了半天,终于把证明什么的都看明白了..推荐一篇博客吧(戳这里),讲的真心不错.. 直接上代码: #include <iostream> # ...

  7. 用GCD线程组与GCD信号量将异步线程转换为同步线程

    用GCD线程组与GCD信号量将异步线程转换为同步线程 有时候我们会碰到这样子的一种情形: 同时获取两个网络请求的数据,但是网络请求是异步的,我们需要获取到两个网络请求的数据之后才能够进行下一步的操作, ...

  8. HDU 5869.Different GCD Subarray Query-区间gcd+树状数组 (神奇的标记右移操作) (2016年ICPC大连网络赛)...

    树状数组... Different GCD Subarray Query Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/6 ...

  9. FVD speed dial-firefox下漂亮和功能强大的快速拨号扩展

    你是否一直使用快速拨号来浏览你最喜爱的网站?那么你就需要一个带有FVD speed dial扩展的firefox浏览器.虽然在火狐之中有很多同类扩展,但是FVD快速拨号应该是其中的上上之作,集人性化. ...

最新文章

  1. Adam 那么棒,为什么还对 SGD 念念不忘?一个框架看懂深度学习优化算法
  2. from torch._C import * ImportError: DLL load failed 动态链接库(DLL)初始化例程失败
  3. 如何在 Kubernetes Pod 内进行网络抓包
  4. 2015/8/18 Python基本使用(2)
  5. oracle多表嵌套查询使用,oracle sql 多表 嵌套子查询 连接查询, join where exist i...
  6. SSRS 2012 高级图表类型 -- 气泡图与散点图
  7. 基于Python的数据分析
  8. 11-24 EDEM-FLUENT 耦合步骤
  9. boot camp驱动下载以及对应机型版本查询
  10. hibernate的注解属性mappedBy详解
  11. python调用java之jpype参数类型转换
  12. windows无法访问 计算机打印机,windows 7 无法连接到打印机 (错误0x0000000d)的解决方法...
  13. double类型判断是否相等
  14. 样式和多级编号的关系
  15. (Tiled官方文档翻译)第四节:对象的编辑和使用
  16. windows 快捷键之新建文件夹
  17. import win32api, sys, os ImportError: DLL load failed: The specified module could not be found.
  18. 【5 操作系统调度】
  19. 生活中正确购买物品你可能真的不会!
  20. 算法面试手撕代码高频题汇集

热门文章

  1. 算法题:用php生成excel列
  2. 基于LBS任务式旅游APP
  3. 模电之半导体基础篇1(本征半导体、杂质半导体)
  4. Imagemotion for Mac(PS动画插件)
  5. Hive启动报错:java.net.URISyntaxException: Relative path in absolute URI: ${system:user.name%7D
  6. python教程68--cufflinks库绘图功能
  7. SAP JCo 3.0 下载
  8. VMware Workstation 12序列号: 5A02H-AU243-TZJ49-GTC7K-3C61N
  9. 银行信贷管理系统的客户关系管理子模块
  10. @Caching,@Cacheable,@CachePut的使用