# JavaScript Program for Range LCM Queries

LCM stands for the lowest common multiple and the LCM of a set of numbers is the lowest number among all the numbers which are divisible by all the numbers present in the given set. We will see the complete code with an explanation for the given problem. In this article, we will implement the JavaScript program for a range of LCM queries.

## Introduction to Problem

In this problem, we are given an array that will contain integers and another array queries that will contain pairwise numbers representing the range from the given array we have to calculate the LCM of all the elements of that given range. For example −

If the given array is: [1, 2, 3, 4, 5, 6] and the queries array is: [ [1,3], [2,5]] then for the first query elements are [2, 3, 4] and 12 is the LCM.

For the second query elements are [3, 4, 5, 6] LCM is 60.

## Mathematical Relation Between LCM and GCD

To find the GCD we have a Euclidian formula by the help of which we can find the GCD of two numbers in logarithmic complexity and there is a relation between the LCM and GCD that −

LCM and GCD of a given set A {a1, a2, a3 …. , an} is:
LCM(A) * GCD(A) = (a1 * a2 * a3* … * an)
OR
LCM(A) = (a1 * a2 * a3 … * an) / GCD(A)


So, we will find the GCD and product of all the numbers, and then from there, we can find the LCM of the number in the O(1) operation.

## Naive Approach

The naive approach is to traverse over the queries array and for each query find the product of the elements in the given range and GCD. From both values find the LCM and return it. Let us implement it in the code −

### Example

// function to find the gcd of the given number
function gcd(a,b){
if (a == 0) {
return b;
}
else {
return gcd(b%a,a);
}
}

// function to find the lcm
function lcmRange(arr, l, r){

// taking gcd as zero because gcd of 0 with any number is that same number
var cur_gcd = 0
var product = 1
var cur_lcm = arr[l]
for(var i = l+1 ;i <= r; i++) {
product = cur_lcm * arr[i];
cur_gcd = gcd(cur_lcm, arr[i])
cur_lcm = product/cur_gcd
}
console.log("The LCM of the element in the given range from " + l + " to " + r + " is: " + cur_lcm);
}

// defining the array
var arr = [ 1, 2, 3, 4, 5, 6]

// defining the queries array
var queries = [[1,3], [2,5]]

// traversing over the array
for(var i = 0; i< queries.length; i++){
lcmRange(arr,queries[i], queries[i])
}


### Time and Space Complexity

The time complexity of the above code is O(Q*N*log(D)), where Q is the number of queries, N is the number of elements in the array, and D is the highest number present in the array.

The space complexity of the above code is O(1), as we are not using any extra space.

In the above program, if the number of queries is equal to N then its time complexity is more than N2 which makes this approach inefficient to use. Let us see it’s another approach &miinus;

## Segment Tree Approach

Segment Tree is an advanced data structure which is used to divide the problem in segments and then joining them all in the terms of power of 2. This takes some space put for range queries, produces the result in logarithmic time. Let us see its code −

### Example

// defining maximum size
var MAX = 1000

// makking tree
var tree = new Array(4*MAX);

// declaring new array
var arr = new Array(MAX);

// function for lcm
function lcm(a, b){
return a*b/gcd(a,b);
}

// function for gcd
function gcd(a, b){
if (a == 0)	{
return b
}
else{
return gcd(b%a,a);
}
}

// Function to creata a segment tree
function build(first, last, cur_node){

// base condition
if (first == last){
tree[cur_node] = arr[first];
return;
}
var mid = (first + last)/2
mid = Math.floor(mid);

// creating left and right segments
build(first, mid, 2*cur_node);
build(mid+1, last, 2*cur_node + 1);

// build the parent for current
var lcm_l = tree[2*cur_node];
var lcm_r = tree[2*cur_node+1];
tree[cur_node] = lcm(lcm_l, lcm_r);
}

// Function to make queries for array range
function query(first, last, l, r, cur_node){

// section out of current range

// 1 is safe to return
if (last < l || first > r){
return 1;
}

// complete inside the current segment
if (l <= first  && r >= last)
return tree[cur_node];

// partially inside the current segment
var mid = (first+last)/2;
mid = Math.floor(mid)
var lcm_l = query(first, mid, l, r, 2*cur_node);
var lcm_r = query(mid+1, last, l, r, 2*cur_node+1);
return lcm(lcm_l, lcm_r);
}

// defining the array
arr = 1;
arr = 2;
arr = 3;
arr = 4;
arr = 5;
arr = 6;

// build the segment tree
build(0, 5, 1);

// defining query array
var queries = [[1,3], [2,5]]

// traversing over the array
for(var i = 0; i< queries.length; i++){
console.log("The LCM of the element in the given range from " + queries[i] + " to " + queries[i] + " is: " + query(0,5,queries[i],queries[i],1) );
}


## Conclusion

In this tutorial, we have implemented a JavaScript article to find the range lcm queries. We have seen two approaches, one is the naive approach with O(Q*N*log(D)) time complexity and another one is by implementing the segment tree with time complexity of O(Q*log(N)).

Updated on: 14-Apr-2023

63 Views 