二进制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. 利用Jquery给当前页或者跳转后页面的导航栏添加选中后样式

    具体的样式有两种情况,一种是直接给当前页面添加特殊样式,当网页刷新或者跳转到下一页后,样式消失:另一种情况是即使刷新页面后样式仍然有效. 直接上代码: 第一种情况: 在CODE上查看代码片派生到我的代 ...

  2. 关于IAP的破解

    介绍 大概在今年7月份,有俄罗斯黑客破解了苹果的应用内付费(In-App Purchases),设备在不越狱的情况下就可以免费获得来自苹果官网App Store里应用的收费道具.受影响的产品众多,包括 ...

  3. Linux_MySql安装

    1.卸载原始mysql-lib sudo rpm -e --nodeps mysql-libs-xx 2.yum安装mysql-server sudo yum -y install mysql -se ...

  4. jq制作博客已存在多少天

    function current(){ var d=new Date(),str=''; var date=((d.getMonth()+1)*30+(d.getFullYear())*365+d.g ...

  5. sql 数据库 初级 个人学习总结(一)

    数据库个人总结(初级)1.增删改查 insert into 表名 values ('条件','条件2') delete from 表名 where 条件 update 表名 set=条件值 where ...

  6. centos重启不能自动联网的解决方法

    在命令行下输入 下面的ifcfg-eth0,eth0为我的网卡名字.机器之间不同,请先查看自己网卡的名字 vi /etc/sysconfig/network-scripts/ifcfg-eth0 进行 ...

  7. php连接多数据库

    <?php $conn1=mysql_connect('localhost','root','','new_link '); $conn2=mysql_connect('localhost',' ...

  8. 20145337实验五Java网络编程及安全

    20145337实验五Java网络编程及安全 实验内容 掌握Socket程序的编写 掌握密码技术的使用 设计安全传输系统 实验步骤 基于Java Socket实现安全传输 基于TCP实现客户端和服务器 ...

  9. 获取 苹果UDID 序列号

    UDID是什么? UDID 是由子母和数字组成的40个字符串的序号,用来区别每一个唯一的iOS设备,包括 iPhones, iPads, 以及 iPod touches,这些编码看起来是随机的,实际上 ...

  10. Java语法基础思维图