二进制GCD

    GCD这种通用的算法相信每个OLER都会 ,辗转相除,代码只有四行 :

int GCD(int a,int b){
if(b==0) return a;
return GCD(b,a%b);
}

  GCD算法使通过辗转相除法来求解两个数的最大公因数,又称欧几里得算法

     可以知道:GCD(x,y)=GCD(x,y-x)

     我们将b能被a整除记作a|b

     那么假设z是最大公因数,那么有:

            如果z|x,z|y,则z|(y-x)  (因为x和y肯定可以写作a*z=x,b*z=y,那么a*z-b*z=(a-b)*z,一定可以整除)

     那么再设z不是x的因子,则z不是x和y-x的公因子

     设z|x.z不是y的因子,则z不是x和y-x的公因子

     那么代码就是上面那个啦!

如果想进一步提高这个算法的效率,那么我们可以选择二进制GCD

    我们可以通过不断地筛去因子2来提高算法的效率,这样的2可以是公共的或单个的,总之不影响算法的正确性

    那么为什么不是筛去因子3、因子4呢?

    因为计算机只提供2进制的快速运算(按位),所以判断a%2=?0可以直接写成!(a&1),但是其它数是没有的,我们知道计算机做取模运算的效率是很低很低的。

    那下面我们来看一看证明过程:

    GCD(x,y)=x   (x==y)

    GCD(x,y)=2*(GCD(x/2,y/2))  (!(x&1) and !(y&1))

    GCD(x,y)=GCD(x/2,y) (!(x&1) and (y&1)    因为2显然不是公因数,所以我们可以果断地筛掉它)

    GCD(x,y)=GCD(x,y/2) ((x&1) and !(y&1)    理由同上)

    GCD(x,y)=GCD(x-y,y) (辗转相减) 

    那么通过上面的推理,我们可以得出代码:

int GCD(int x,int y){
int i=0,j=0;
if(x==0) return y;//if和for一定不能反,要么会炸
if(y==0) return x;//一个没用了就返回另一个
for(i;0==(x&1);i++) x>>=1;//化简为n*(m^2)形式
for(j;0==(y&1);j++) y>>=1;//化简为a*(b^2)形式
if(i>j) i=j;//去最大 公 因数,当然是你有我有的了
while(1){
if(x<y) x^=y,y^=x,x^=y;//二进制交换,非常高级
if(0==(x-=y)) return y<<i;//那么就把以前的次幂乘上去,辗转减操作
while(0==(x&1)) x>>=1;//x减了y以后可能还是成为a*(b^2)形式,要继续筛去
}
}

  

至于LCM(最小公倍数)来说有如下定理:

    x*y=LCM(x,y)*GCD(x,y),那么只需要求出GCD以后算一下x*y/GCD(x,y)就好了

【数论】二进制GCD的更多相关文章

  1. 二进制GCD算法解析

    UPD 2018.3.30 这个好像就是更相减损术的样子emmm UPD 2018.5.22 好像不是更相减损术而是叫Stein算法的样子emmm 蒟蒻来做个二进制GCD笔记. 为什么要写这个东西呢, ...

  2. 二进制GCD

    目录 写在前面 具体实现: Code 写在前面 全程抄书 想要进一步提高求 \(\gcd\) 的效率,可以通过不断去除因子 \(2\) 来降低常数,这就是"二进制 \(\gcd\) &quo ...

  3. 二进制GCD算法 减少%的时间消耗

    /* 二进制求最大公约数.由于传统的GCD,使用了%,在计算机运行过程中要花费大量的时间,所以,采取二进制的求法,来减少时间的消耗. 算法: 当a,b都是偶数时: gcd(a,b)=2*gcd(a/2 ...

  4. CodeForces - 984C——Finite or not?分数整除问题(数论,gcd)

    题目传送门 题目描述:给你一个p/q,让你求在b进制下,这个小数是不是有限小数. 思路: 先来膜拜一个大神的博客,如何求小数的二进制表达,(感谢博主肘子zhouzi).然后小数的其他进制表达也一样. ...

  5. HDU - 5050 (大数二进制gcd)

    It's time to fight the local despots and redistribute the land. There is a rectangular piece of land ...

  6. 数论3——gcd&&lcm

    gcd(a, b),就是求a和b的最大公约数 lcm(a, b),就是求a和b的最小公倍数 然后有个公式 a*b = gcd * lcm     ( gcd就是gcd(a, b), ( •̀∀•́ ) ...

  7. codeforce#483div2C-Finite or not?数论,GCD

    传送门:http://codeforces.com/contest/984/problem/C 这道题 题意:求q/p是否能用k进制有限表示小数点后的数:   思路:数学推理:     1.首先把q/ ...

  8. C. Neko does Maths(数论 二进制枚举因数)

     题目链接:https://codeforces.com/contest/1152/problem/C 题目大意:给你a和b,然后让你找到一个k,使得a+k和b+k的lcm. 学习网址:https:/ ...

  9. 用二进制方法求两个整数的最大公约数(GCD)

    二进制GCD算法基本原理是: 先用移位的方式对两个数除2,直到两个数不同时为偶数.然后将剩下的偶数(如果有的话)做同样的操作,这样做的原因是如果u和v中u为偶数,v为奇数,则有gcd(u,v)=gcd ...

随机推荐

  1. Oracle 建立索引及SQL优化

    数据库索引: 索引有单列索引,复合索引之说,如果某表的某个字段有主键约束和唯一性约束,则Oracle 则会自动在相应的约束列上建议唯一索引.数据库索引主要进行提高访问速度. 建设原则: 1.索引应该经 ...

  2. linux pidof

    转载:http://blog.51osos.com/linux/linux-pidof-command/ 什么是pidof命令? #man pidof中的解释: pidof — find the pr ...

  3. [LintCode] Reverse Integer 翻转整数

    Reverse digits of an integer. Returns 0 when the reversed integer overflows (signed 32-bit integer). ...

  4. 19.创建如下三个类:(People类中的三个方法分别输出一些信息,ChinaPeople 和AmericanPeople类重写父类的三个方法)。

    package zuoye2; public class People { protected double height; protected double weight; private Stri ...

  5. 三种线程不安全现象描述(escaped state以及hidden mutable state)

    hidden mutable state和escaped state是两种线程不安全问题:两者原因不同,前者主要是由于类成员变量中含有其他对象的引用,而这个引用是immutable的:后者是成员方法的 ...

  6. nfs基本配置

    一.安装nfs: yum install nfs-utils rpcbind 创建共享目录:mkdir -p /XXX/export/ 修改配置文件:vim /etc/exports /XXX/exp ...

  7. JS分页方法

    /** maxpage 最大页数 */function gotoPage(maxpage){         var gotoPage = document.getElementById(" ...

  8. Web前端开发基础 第四课(CSS小技巧1)

    垂直居中-父元素高度确定的单行文本 父元素高度确定的单行文本的竖直居中的方法是通过设置父元素的 height 和 line-height 高度一致来实现的.如下代码: <div class=&q ...

  9. 实现服务器端与客户端的实时通信 SignalR(1)

    一.本文出处:SignalR 实例介绍 (建议看原著里面有DEMO下载) 二.这篇文章介绍如何利用 VS2012 创建一个简单的实时聊天系统,建好后的样子如下(模拟三个在线用户):    三.Demo ...

  10. ThinkPHP 3.2.3 视图模型的使用

    ThinkPHP 3.2.3 试图模型的手册地址是:http://www.kancloud.cn/manual/thinkphp/1781 实例 需求:在博客列表页读取博客的(id.标题.摘要.发布时 ...