题目详情
小强最近在学初等数论,老师给他们出了一个课后习题,那就是给你两个正整数A,B(0<A,B<2^60),判断他们的素因子集合是否相同,小强刚接触数论,想了好一会还是没能想出来,你能帮助他吗?
输入描述:
输入包含多组测试数据,每组测试数据包含两个正整数A,B,以文件结束。
输出描述:
对于每组测试数据如果A和B的素因子集合相同则输出“YES”,否则输出“NO”。
答题说明
输入样例:
2 8
4 9
10 50
输出样例:
YES
NO
YES
思路:这个问题可分解为a的素数因子集合是否属于b的和b的素数因子集合是否属于a的,对于a的素数因子集合是
否属于b的,我们可以不断的求a与b的最大公约数,然后整除a,直到a等于1(即“yes”),或者最大公约数为1
(即“no”),求最大公约数我用的是二进制欧几里得什么的(我也不知道叫什么名字,反正知道怎么用),好
像蛮快得。
代码如下:
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
#define inf 0x7fffffff
#define MOD 1000000007
using namespace std;
__int64 getGcd(__int64 a, __int64 b) {
if(b == 0) {
return a;
}
if(a == 0) {
return b;
}
if((a&1)==0) {
if((b&1)==0)
return 2*getGcd(a>>1, b>>1);
else
return getGcd(a>>1, b);
} else {
if((b&1)==0)
return getGcd(a, b>>1);
else {
if(a < b)
swap(a, b);
return getGcd((a-b)>>1, b);
}
}
}
int main() {
__int64 a, b;
while(scanf("%I64d%I64d", &a, &b)!=EOF) {
__int64 t = b;
while(t != 1) {
__int64 gcd = getGcd(a, t);
if(gcd == 1)
break;
t /= gcd;
}
if(t != 1) {
printf("NO\n");
} else {
while(a != 1) {
__int64 gcd = getGcd(a, b);
if(gcd == 1)
break;
a /= gcd;
}
if(a != 1) {
printf("NO\n");
} else {
printf("YES\n");
}
}
}
return 0;
}