二进制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. android中的ActionBar和ToolBar

    一.ToolBar 1.概述 Google在2015的IO大会上发布了系列的Material Design风格的控件.其中ToolBar是替代ActionBar的控件.由于ActionBar在各个安卓 ...

  2. [LintCode] Submatrix Sum 子矩阵之和

    Given an integer matrix, find a submatrix where the sum of numbers is zero. Your code should return ...

  3. 20个有用的jq弹窗

    链接地址:http://www.ffpic.com/zixun/20-useful-jquery-modal-plugins.html 推荐:jQuery.bPopup.js

  4. JSP + AJAX完整实例及代码

    (1)发送请求index.jsp,注意引入jquery.min.js文件 <%@ page language="java" contentType="text/ht ...

  5. bootstrap使用性能问题

    1.如icheckbox等的初始化,不要采用类似for in的循环来对所需应用的元素进行初始化,直接采用如  $('[data-toggle="popover"]').popove ...

  6. eclipse中如何修改dynamic web module version

    java项目中,若切换服务器,经常会涉及到动态web模块版本的问题.      比如:新建了web项目,开始使用tomcat服务器,但是后来使用jboss服务器,就会出现:Project facet ...

  7. 64位虚拟机安装64位ubuntu出现问题

    virtualbox 出现this kernel requires an an x86-64 cpu 错误 如题,但是主机是win8 64位,使用virtualbox安装ubuntu-12.04.3- ...

  8. bzoj3991: [SDOI2015]寻宝游戏--DFS序+LCA+set动态维护

    之前貌似在hdu还是poj上写过这道题. #include<stdio.h> #include<string.h> #include<algorithm> #inc ...

  9. Java面试题大全(一)

    JAVA相关基础知识 1.面向对象的特征有哪些方面 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分, ...

  10. c++ basic 整理2

    ​//拷贝函数 //拷贝构造函数是一种特殊的构造函数,函数的名称必须和类名称一致,它必须的一个参数是本类型的一个引用变量. //不显式指定拷贝函数时,编译器会生成默认拷贝函数. //使用默认拷贝函数 ...