forked from kamyu104/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
greatest-common-divisor-traversal.cpp
79 lines (75 loc) · 2.53 KB
/
greatest-common-divisor-traversal.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// Time: precompute: O(sqrt(r)), r = max(nums)
// runtime: O(n * (logr + pi(sqrt(r))) = O(n * (logr + sqrt(r)/log(sqrt(r)))), pi(n) = number of primes in a range [1, n] = O(n/logn) by prime number theorem, see https://en.wikipedia.org/wiki/Prime_number_theorem
// Space: O(sqrt(r) + nlogr)
// linear sieve of eratosthenes, number theory, bfs
vector<int64_t> linear_sieve_of_eratosthenes(int64_t n) { // Time: O(n), Space: O(n)
vector<int64_t> spf(n + 1, -1);
vector<int64_t> primes;
for (int64_t i = 2; i <= n; ++i) {
if (spf[i] == -1) {
spf[i] = i;
primes.emplace_back(i);
}
for (const auto& p : primes) {
if (i * p > n || p > spf[i]) {
break;
}
spf[i * p] = p;
}
}
return primes;
}
static const int MAX_VALUE = 1e5;
const auto& PRIMES = linear_sieve_of_eratosthenes(sqrt(MAX_VALUE));
class Solution {
public:
bool canTraverseAllPairs(vector<int>& nums) {
const auto& prime_factors = [&](int x) {
unordered_map<int, int> factors;
for (const auto& p : PRIMES) {
if (p * p > x) {
break;
}
for (; x % p == 0; x /= p) {
++factors[p];
}
}
if (x != 1) {
++factors[x];
}
return factors;
};
vector<vector<int>> adj(size(nums));
const auto& bfs = [&]() {
vector<bool> lookup(size(nums));
lookup[0] = true;
vector<int> q = {0};
while (!empty(q)) {
vector<int> new_q;
for (const auto& u : q) {
for (const auto& v : adj[u]) {
if (lookup[v]) {
continue;
}
lookup[v] = true;
new_q.emplace_back(v);
}
}
q = move(new_q);
}
return all_of(cbegin(lookup), cend(lookup), [](int x) { return x; });
};
unordered_map<int, int> lookup;
for (int i = 0; i < size(nums); ++i) {
for (const auto& [p, _] : prime_factors(nums[i])) {
if (!lookup.count(p)) {
lookup[p] = i;
continue;
}
adj[i].emplace_back(lookup[p]);
adj[lookup[p]].emplace_back(i);
}
}
return bfs();
}
};