题目链接
本题主要是对数组中是否存在一个数与其他所有数互质的判断
枚举求最大公约数时间复杂度是O(N * N * logN)会超时。
解法:对每个数分解质因数,记录数组中每个质因数的个数之和,再用一个数组存每个质因数在某个数中出现的次数
再次遍历数组中的每一个数,若这个数有这个质因数且数组中的质因数个数 > 该数的质因数个数,说明数组中的另一个数存在该质因数,即存在一个数与这个数不互质。
#include <iostream>
#include <cstring>
#include <vector>
#include <unordered_map>
#include <cstdio>
#include <cstdlib>
using namespace std;
const int N = 1000010, M = 100;
int primes[N], n, m, a[N], cnt;
bool st[N];
int mind[N];
unordered_map<int, int> whole;
int gcd(int a, int b) {
return b ? gcd(b, a % b) : a;
}
void make_primes(int n) {
for (int i = 2; i < n; i ++) {
if (!st[i]) primes[cnt ++] = i;
for (int j = 0; primes[j] <= n / i; j ++) {
st[primes[j] * i] = 1;
if (i % primes[j] == 0) break;
}
}
}
bool pairwise() {
for (int i = 0; i < n; i ++) {
int t = a[i];
for (int j = 2; j <= t / j; j ++) { //分解质因数
if (t % j == 0) {
int s = 0;
while (t % j == 0) s ++, t/= j;
whole[j] += s;
mind[j] = min(mind[j], s);
}
}
if (t > 1) whole[t] += 1, mind[t] = min(mind[t], 1);
}
for (int i = 0; i < cnt; i ++) { //判断相同的质因数是否全部来自同一个数
int p = primes[i];
if (mind[p] < whole[p]) return false;
}
return true;
}
bool setwise() {
int x = a[0];
for (int i = 0; i < n; i ++) {
x = gcd(x, a[i]);
if (x == 1) return true;
}
return false;
}
int main() {
memset(mind, 0x3f, sizeof mind);
cin >> n;
make_primes(N);
for (int i = 0; i < n; i ++)
cin >> a[i];
if (pairwise ()) {
cout << "pairwise coprime";
}
else {
if (setwise()) cout << "setwise coprime";
else cout << "not coprime";
}
return 0;
}