// Function to create a new set with element 'v'
function makeSet(v, parent, rnk) {
parent[v] = v;
rnk[v] = 0;
}
// Function to find the representative (parent) of a set containing 'v'
function findPar(v, parent) {
if (v === parent[v]) {
return v;
}
// Path compression for optimization
parent[v] = findPar(parent[v], parent);
return parent[v];
}
// Function to union two sets with elements 'a' and 'b'
function unionSets(a, b, parent, rnk) {
a = findPar(a, parent);
b = findPar(b, parent);
if (a !== b) {
if (rnk[a] < rnk[b]) {
[rnk[a], rnk[b]] = [rnk[b], rnk[a]];
}
parent[b] = a;
if (rnk[a] === rnk[b]) {
rnk[a]++;
}
}
}
// Function to solve the problem and find the Minimum Spanning Tree (MST)
function solve(a, n, k) {
const vp = Array.from({ length: n }, (_, i) => ({ value: a[i], index: i }));
// Sort elements by their values
vp.sort((x, y) => x.value - y.value);
// Initialize disjoint-set data structures for each element
const parent = new Array(n);
const rnk = new Array(n);
for (let i = 0; i < n; i++) {
makeSet(i, parent, rnk);
}
let j = 0;
// Initialize the total weight of the MST
let ans = 0;
while (j < n) {
// Get the original index of the element
const idx = vp[j].index;
// If the element value is greater than 'k', break
if (vp[j].value > k) {
break;
}
let i = idx + 1;
// Initialize the current GCD value
let currGcd = a[idx];
// Explore elements to the right
while (i < n && currGcd === a[idx]) {
// Calculate the GCD
currGcd = gcd(currGcd, a[i]);
// If the GCD condition is not met, break
if (currGcd !== a[idx]) {
break;
}
const x = findPar(idx, parent);
const y = findPar(i, parent);
// If they are already in the same component, break
if (x === y) {
break;
}
// Union two sets and update 'ans'
unionSets(x, y, parent, rnk);
ans += a[idx];
i++;
}
// Explore elements to the left
i = idx - 1;
currGcd = a[idx];
while (i >= 0 && currGcd === a[idx]) {
currGcd = gcd(currGcd, a[i]);
// If the GCD condition is not met, break
if (currGcd !== a[idx]) {
break;
}
const x = findPar(idx, parent);
const y = findPar(i, parent);
// If they are already in the same component, break
if (x === y) {
break;
}
unionSets(x, y, parent, rnk);
ans += a[idx];
i--;
}
j++;
}
// Add edges with weight 'k' between adjacent elements
for (let i = 0; i < n - 1; i++) {
const x = findPar(i, parent);
const y = findPar(i + 1, parent);
if (x !== y) {
unionSets(x, y, parent, rnk);
// Update 'ans' with the edge weight 'k'
ans += k;
}
}
// Return the total weight of the MST
return ans;
}
// Utility function to calculate GCD
function gcd(a, b) {
return b === 0 ? a : gcd(b, a % b);
}
// Driver Code
const N = 4, K = 5;
const a = [3, 2, 6, 3];
const result = solve(a, N, K);
// Print the total weight of the MST
console.log(result);