CF1025B Weakened Common Divisor
与 GCD (最大公约数)类似,我们引进 WCD (弱公约数)的概念, WCD 的定义如下:
给出几对数(a1,b1),(a2,b2),⋯,(an,bn) ,它们的 WCD 满足大于 1 ,且能整除每个数对中至少一个数。 WCD 在一些情况下,可能不存在。
例如,给出这几对数[(12,15),(25,18),(10,24)] ,它们的 WCD可以是 2,3,5,6 (这些数都满足严格大于 1,且能整除每个数对中至少一个数)
现在给你几对数,求他们的 WCD 。
输入输出格式
输入格式
第一行一个整数 n , 1⩽n⩽150 000 表示数对的组数。
接下来 n 行,每行两个整数 2⩽ai,bi⩽2⋅10^9
输出格式
一个整数,表示这些数对的 WCD ,如果这些数对不存在 WCD ,输出 −1 。
样例解释
第一组样例中, 6 可以分别整除 18,24,12 ,当然输出其他可能的答案也行。
第二个样例,没有满足条件的 WCD。
第三个样例,可以是 5 ,当然也可以是 3,15 等。你没有必要输出最大或者最小的答案。
这里有中文,就不解释题意了。
思路:因为一个数所有的因子都是由质因子构成,所以可以只判断质因子。直接找出前两个数所有的质因子,然后直接暴力判断就可以了。因为一个数的质因子很少,2e9 里面的数最多的也就 8 ,9个质因子,然后暴力判断 n 对数,复杂度是完全没问题的。
AC代码:
#include<bits/stdc++.h>
#define debug(x) cout << "[" << #x <<": " << (x) <<"]"<< endl
#define clr(a,b) memset((a),b,sizeof(a))
#define rep(i,a,b) for(int i = a;i < b;i ++)
#define LL long long
#define INT(t) int t; scanf("%d",&t)
#define LLI(t) LL t; scanf("%I64d",&t)
using namespace std;
const int maxn = 1e5 + 60000;
int a[maxn], b[maxn];
set<int> pr_div;
void prime_divi(int x){
for(int i = 2;i <= sqrt(x);i ++)
while(x % i == 0){
pr_div.insert(i);
x /= i;
}
if(x > 1) pr_div.insert(x);
}
int main() {
int n;
while(~scanf("%d", &n)) {
rep(i,1,n + 1)
scanf("%d%d", &a[i], &b[i]);
pr_div.clear();
prime_divi(a[1]); prime_divi(b[1]);
set<int>::iterator it;
bool ok = false;
for(it = pr_div.begin();it != pr_div.end();it ++){
int flag = 1;
int tmp = * it;
rep(i,2,n + 1){
if(a[i] % tmp != 0 && b[i] % tmp != 0){
flag = 0;
break;
}
}
if(flag){ printf("%d\n",tmp); ok = true; break; }
}
if(!ok) printf("-1\n");
}
return 0;
}