-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGCDTraversal.java
More file actions
89 lines (71 loc) · 2.34 KB
/
GCDTraversal.java
File metadata and controls
89 lines (71 loc) · 2.34 KB
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
80
81
82
83
84
85
86
87
88
89
package graph;
import java.util.*;
/**
* Hard On DSU, Crazy Technique!
*/
public class GCDTraversal {
static int[] father;
public static boolean canTraverseAllPairs(int[] nums) {
int n = nums.length;
int max = -1;
for (int x : nums) max = Math.max(max, x);
// Getting primes till max using eratosthenes.
List<Integer> primes = eratosthenes(max);
int m = primes.size();
Map<Integer, Integer> primeIndex = new HashMap<>();
for (int i = 0; i < m; i++) primeIndex.put(primes.get(i), i);
// Initialization on DSU.
father = new int[n + m];
for (int i = 0; i < n + m; i++)
father[i] = i;
for (int i = 0; i < n; i++) {
int x = nums[i];
for (int j = 0; j < m; j++) {
int p = primes.get(j);
if (p > x) break;
if (p * p > x) {
if (findFather(i) != findFather(n + primeIndex.get(x)))
union(i, n + primeIndex.get(x));
break;
}
if (x % p == 0) {
if (findFather(i) != findFather(n + j))
union(i, n + j);
while (x % p == 0)
x /= p;
}
}
}
for (int i = 1; i < n; i++) {
if (findFather(i) != findFather(i - 1)) return false;
}
return true;
}
// To find prime numbers till n. (n * log(log(n))).
private static List<Integer> eratosthenes(int n) {
boolean[] visited = new boolean[n + 1];
for (int i = 2; i <= (int) Math.sqrt(n); i++) {
if (visited[i]) continue;
// Table of i.
for (int j = i * 2; j <= n; j += i)
visited[j] = true;
}
List<Integer> primes = new ArrayList<>();
for (int i = 2; i <= n; i++) {
if (!visited[i]) primes.add(i);
}
return primes;
}
// Parent function of DSU.
private static int findFather(int x) {
if (father[x] != x) father[x] = findFather(father[x]);
return father[x];
}
// Union function of DSU.
private static void union(int x, int y) {
x = father[x];
y = father[y];
if (x < y) father[y] = x;
else father[x] = y;
}
}