2
private static final int[] primes;4
// precompute prime numbers6
primes = new int[5133];7
final int max = 100000 / 2;8
boolean[] notprime = new boolean[max];9
for (int index = 0, i = 2; i < max; i++) {10
if (notprime[i]) continue;12
for (int j = (max - 1) / i; j >= 2; j--) notprime[i * j] = true;16
public boolean gcdSort(int[] nums) {17
final var sorted = nums.clone();19
final int len = nums.length, max = sorted[len - 1];20
final int[] map = new int[max + 1]; // grouping tree child->parent21
for (int i = 0; i < len; i++) map[nums[i]] = nums[i];23
for (final var p : primes) {24
if (p > max / 2) break;27
for (int num = p + p; num <= max; num += p) {28
var existing = map[num];29
if (existing == 0) continue; // value doens't exist in array30
if (existing == num) map[num] = group; // 1st hit, set group, otherwise, group merging31
else if ((existing = root(map, existing)) < group) {32
map[group] = existing;34
} else map[existing] = group;38
for (int i = 0; i < len; i++) if (root(map, nums[i]) != root(map, (sorted[i]))) return false;42
private static int root(int[] map, int num) {44
while (num != (group = map[num])) num = group;