最大公约数、最小公倍数【模板】

2024-06-15 05:48

本文主要是介绍最大公约数、最小公倍数【模板】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最大公约数、最小公倍数性质:

1.若a | m,b | m,则lcm(a,b) | m。

2.若d | a,d | b,则d | gcd(a,b)。

3.lcm(a,b) = a * b / gcd(a,b)。

4.设m,a,b是正整数,则lcm(m*a,m*b) = m * gcd(a,b)

5.若m是非零整数a1,a2,…,an的公倍数,则lcm(a1,a2,…,an) | m。

用素因子分解法求a和b的最大公约数和最小公倍数:

a = p1^r1 * p2^r2 * … * pk^rk

b = p1^s1 * p2*s2 * … * pk^sk

gcd(a,b) = p1^min(r1,s1) * p2^min(r2,s2) * … * pk^min(rk,sk)

lcm(a,b) = p1^max(r1,s1) * p2^max(r2,s2) * … * pk^max(rk,sk)

最大公约数:

欧几里得算法O(n)

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

Stein算法O( log(max(a,b)) )

int KGCD(int a,int b)
{if(a == 0)	return b;if(b == 0)	return a;if(~a & 1){if(b & 1)	return KGCD(a>>1, b);else	return KGCD(a>>1, b>>1) << 1;}if(~b & 1)	return KGCD(a, b>>1);if(a > b)	return KGCD((a-b)>>1, b);return	KGCD((b-a)>>1, a);
}


最小公倍数:

int LCM(int a,int b)
{return a/KGCD(a,b)*b;
}

欧几里得算法O(n)实现原理:

设两数为a、b(a>b),求a和b最大公约数(a,b)的步骤如下:

用b除a,得a÷b=q......r1(0≤r1)。若r1=0,则(a,b)=b;

若r1≠0,则再用r1除b,得b÷r1=q......r2 (0≤r2).

若r2=0,则(a,b)=r1,若r2≠0,则继续用r2除r1,……

如此下去,直到能整除为止。其最后一个非零除数即为(a,b)。


stein算法O( log(max(a,b)) )实现原理:
gcd(a,a)=a,也就是一个数和其自身的公约数仍是其自身。gcd(ka,kb)=k gcd(a,b),也就是最大

公约数运算和倍乘运算可以交换。特殊地,当k=2时,说明两个偶数的最大公约数必然能被2整除。
当k与b互为质数,gcd(ka,b)=gcd(a,b),也就是约掉两个数中只有其中一个含有的因子不影响最

大公约数。特殊地,当k=2时,说明计算一个偶数和一个奇数的最大公约数时,可以先将偶数除以

2。
算法过程:
1、如果An=Bn,那么An(或Bn)*Cn是最大公约数,算法结束
2、如果An=0,Bn是最大公约数,算法结束
3、如果Bn=0,An是最大公约数,算法结束
4、设置A1=A、B1=B和C1=1
5、如果An和Bn都是偶数,则An+1=An/2,Bn+1=Bn/2,Cn+1=Cn*2(注意,乘2只要把整数左移一位

即可,除2只要把整数右移一位即可)
6、如果An是偶数,Bn不是偶数,则An+1=An/2,Bn+1=Bn,Cn+1=Cn(很显然啦,2不是奇数的约数)
7、如果Bn是偶数,An不是偶数,则Bn+1=Bn/2,An+1=An,Cn+1=Cn(很显然啦,2不是奇数的约数)
8、如果An和Bn都不是偶数,则An+1=|An-Bn|/2,Bn+1=min(An,Bn),Cn+1=Cn
9、n加1,转1

这篇关于最大公约数、最小公倍数【模板】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1062594

相关文章

poj3468(线段树成段更新模板题)

题意:包括两个操作:1、将[a.b]上的数字加上v;2、查询区间[a,b]上的和 下面的介绍是下解题思路: 首先介绍  lazy-tag思想:用一个变量记录每一个线段树节点的变化值,当这部分线段的一致性被破坏我们就将这个变化值传递给子区间,大大增加了线段树的效率。 比如现在需要对[a,b]区间值进行加c操作,那么就从根节点[1,n]开始调用update函数进行操作,如果刚好执行到一个子节点,

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

poj 1287 Networking(prim or kruscal最小生成树)

题意给你点与点间距离,求最小生成树。 注意点是,两点之间可能有不同的路,输入的时候选择最小的,和之前有道最短路WA的题目类似。 prim代码: #include<stdio.h>const int MaxN = 51;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int P;int prim(){bool vis[MaxN];

poj 2349 Arctic Network uva 10369(prim or kruscal最小生成树)

题目很麻烦,因为不熟悉最小生成树的算法调试了好久。 感觉网上的题目解释都没说得很清楚,不适合新手。自己写一个。 题意:给你点的坐标,然后两点间可以有两种方式来通信:第一种是卫星通信,第二种是无线电通信。 卫星通信:任何两个有卫星频道的点间都可以直接建立连接,与点间的距离无关; 无线电通信:两个点之间的距离不能超过D,无线电收发器的功率越大,D越大,越昂贵。 计算无线电收发器D

poj 1734 (floyd求最小环并打印路径)

题意: 求图中的一个最小环,并打印路径。 解析: ans 保存最小环长度。 一直wa,最后终于找到原因,inf开太大爆掉了。。。 虽然0x3f3f3f3f用memset好用,但是还是有局限性。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#incl

hdu 1102 uva 10397(最小生成树prim)

hdu 1102: 题意: 给一个邻接矩阵,给一些村庄间已经修的路,问最小生成树。 解析: 把已经修的路的权值改为0,套个prim()。 注意prim 最外层循坏为n-1。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstri

uva 1342 欧拉定理(计算几何模板)

题意: 给几个点,把这几个点用直线连起来,求这些直线把平面分成了几个。 解析: 欧拉定理: 顶点数 + 面数 - 边数= 2。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#inc

uva 11178 计算集合模板题

题意: 求三角形行三个角三等分点射线交出的内三角形坐标。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <

poj 2175 最小费用最大流TLE

题意: 一条街上有n个大楼,坐标为xi,yi,bi个人在里面工作。 然后防空洞的坐标为pj,qj,可以容纳cj个人。 从大楼i中的人到防空洞j去避难所需的时间为 abs(xi - pi) + (yi - qi) + 1。 现在设计了一个避难计划,指定从大楼i到防空洞j避难的人数 eij。 判断如果按照原计划进行,所有人避难所用的时间总和是不是最小的。 若是,输出“OPETIMAL",若