5.唯一分解定理、GCD、LCM

模板

唯一分解定理

任何一个大于1的自然数 ,都可以唯一分解成有限个质数的乘积。

GCD(最大公约数)

欧几里德算法(辗转相除法)
gcd(a,b)=gcd(b,a%b)

 若d能整除a、d能整除b,那么d能整除(a+b)=>若d能整除a、d能整除b,那么d能整除(xa+yb)
a%b=a-a/b*b
=>a%b=a-c*b
若d能整除a、d能整除b,那么d能整除a-c*b
若d能整除a-c*b、d能整除b,那么d能整除a
所以gcd(a,b)=gcd(b,a%b)

代码:

int gcd(int x,int y)
{
	return y?gcd(y,x%y):x; //gcd(x,0)=x
}

⭐⭐扩展欧几里德定理:
已知a, b求解一组x,y使得ax+by =c
若 c%gcd(a,b)!=0,则无解。
所以,我们求ax+by=c可以转化为求 ax+by=k*gcd(a,b) (k为整数)。

LCM(最小公倍数)

a*b=gcd(a,b)*lcm(a,b)

所以lcm(a,b)=a*b/gcd(a,b)
不过最好写为lcm(a,b)=a/gcd(a,b)*b
可以一定程度上避免a*b爆long long。

练习

C - Wolf and Rabbit(欧几里德的扩展)

There is a hill with n holes around.The holes are signed from 0 to n-1.
A rabbit must hide in one of the holes. A wolf searches the rabbit in anticlockwise order. The first hole he get into is the one signed with 0. Then he will get into the hole every m holes. For example, m=2 and n=6, the wolf will get into the holes which are signed 0,2,4,0. If the rabbit hides in the hole which signed 1,3 or 5, she will survive. So we call these holes the safe holes.
Input
The input starts with a positive integer P which indicates the number of test cases. Then on the following P lines,each line consists 2 positive integer m and n(0<m,n<2147483648).
Output
For each input m n, if safe holes exist, you should output “YES”, else output “NO” in a single line.
Sample Input
2
1 2
2 2
Sample Output
NO
YES
思路:
设狼走了k次到达标号为p的洞穴,则

k*m-t*n=p

要使该方程有解,那么p%(gcd(m,n))=0。(欧几里得的扩展)。
要使狼走过每一个洞穴,那么该方程必须在p取0、1、2····n-1时都有解,即p%(gcd(m,n))==0,所以只有gcd(m,n)==1即m、n互质时,狼可以遍历每个洞穴。

AC代码

#include <iostream>
using namespace std;
typedef long long ll;
ll gcd(ll x,ll y)
{
	return y?gcd(y,x%y):x;
}
int main()
{
	ll p;
	cin>>p;
	while(p--)
	{
		ll m,n;
		cin>>m>>n;
		if(gcd(m,n)==1)	cout<<"NO"<<endl;
		else	cout<<"YES"<<endl;
	}
	return 0;
}

D - Cake(数学思维、模拟)

一次生日Party可能有p人或者q人参加,现准备有一个大蛋糕.问最少要将蛋糕切成多少块(每块大小不一定相等),才能使p人或者q人出席的任何一种情况,都能平均将蛋糕分食.
Input
每行有两个数p和q.
Output
输出最少要将蛋糕切成多少块.
Sample Input
2 3
Sample Output
4
Hint
将蛋糕切成大小分别为1/3,1/3,1/6,1/6的四块即满足要求.
当2个人来时,每人可以吃1/3+1/6=1/2 , 1/2块。
当3个人来时,每人可以吃1/6+1/6=1/3 , 1/3, 1/3块。
AC代码

#include <iostream>
#include <cmath>
using namespace std;
int gcd(int x,int y)
{
	return y?gcd(y,x%y):x;
}
int main()
{
	int p,q;
	while(cin>>p>>q)
		cout<<p+q-gcd(p,q)<<endl;
		//gcd表示重复切的刀数
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值