C++ Program for range LCM queries


Ranging a query is a common database current interest operation present in data structure to restore all the records where the output value lies between an upper and lower boundary. This process works with some input data, to structure them in an efficient manner on any subset of a particular input. The range function, denoted as range(), is used to iterate a for loop over a series. We need to declare the start as 0 at the beginning of a process. If somehow we miss this step, the process will run and iterate the loop until the end (-1).

A range is a minimum and maximum value which can be stored inside a variable. They are generated with an operator and used to call arrays of the variables. This range returns an output list present in a range between x to y-1.

Example

Let’s assume, we have an array set of integers and we need to evaluate the query in the form of LCM(a,r). Hence, we have to evaluate the queries in an efficient manner.

LCM(a,r) denotes the least common multiple of an array that present in betweenthe index a and r. Here both indicates are inclusive in manner.

Mathematucally we all know; L.C.M. = L.C.M Of Numerator/H.C.F Of Denominator.

So, by using this logic we can follow the rule to range LCM query written below:

LCM(a, r) = LCM(arr[a], arr[a+1] , ......... ,arr[r-1], arr[r])

Applying This Logic:

Input –

arr[0] = 5;
arr[1] = 7;
arr[2] = 5;
arr[3] = 2;
arr[4] = 10;
arr[5] = 12;
arr[6] = 11;
arr[7] = 17;
arr[8] = 14;
arr[9] = 1;
arr[10] = 44;
C++ Program for range LCM queries
build(1, 0, 10);
cout << query(1, 0, 10, 2, 5) << endl;
cout << query(1, 0, 10, 5, 10) << endl;
cout << query(1, 0, 10, 0, 10) << endl;

Output –

60
15708
78540

The time complexity of this particular process denoted as O(Log N * Log n). Here N is the total numbers of elements present in an array. We need to declare the Log n as the time requirement finder for the LCM operation in a particular coding environment and O(N) time is required to bulid a tree to get an output from the written program. It also indicates the space requirement for the process.

Algorithm to range LCM queries:-

  • Step 1 − Start

  • Step 2 − Initialize the two numbers of variables for tow numbers.

  • Step 3 − Find the storage value for each number.

  • Step 4 − Separate the variable with a 'max' function.

  • Step 5 − If, the max is divisible by the first number and also with the second.

  • Step 6 − Print the max as LCM.

  • Step 7 − Else, it is not divisible then increase it by 1.

  • Step 8 − Then again go for step five, until a number has been printed.

  • Step 9 − Repeat the process until max value is found which satisfies the condition.

  • Step 10 − Terminate.

Syntax to range LCM query

int find_therangelcm(int a, int tl, int ts, int r) {
   if (r > t[a])
      return -1;
   if (tl == ts)
      return tl;
   int tm = (tl + ts) / 2;
   if (t[a*2] >= r)
      return find_therangelcm(a*2, tl, tm, r);
   else
   return find_therangelcm(a*2+1, tm+1, ts, r - t[a*2]);
}

In this syntax, we have explained how to range a LCM queries in a particular coding environment.

Approach

  • Approach 1 − The naïve approach by using a segment tree.

  • Approach 2 − Find LCM of two in a general way.

The naïve approach by using a segment tree

There is no update operation for this problem but naive approach is not the right one alone. We need to implement a segment tree to get the possible result. Here we will use a logic −

LCM(a, b) = (a*b) / GCD(a,b)

Here is the implementation steps −

  • Built segment tree for the array.

  • Traverse the particular range of segment tree.

  • Calculate the LCMfrom that range.

  • Print the answer for that segment.

Example 1

#include <bits/stdc++.h>
using namespace std;
#define MAX 1000
int tree[4 * MAX];
int arr[MAX];
int gcd(int a, int b) {
   if (a == 0)
   return b;
   return gcd(b % a, a);
}
int lcm(int a, int b) { return a * b / gcd(a, b); }
   void build(int node, int start, int end) {
   if (start == end) {
      tree[node] = arr[start];
      return;
   }
   int mid = (start + end) / 2;
   build(2 * node, start, mid);
   build(2 * node + 1, mid + 1, end);
   
   // build the parent
   int left_lcm = tree[2 * node];
   int right_lcm = tree[2 * node + 1];
   tree[node] = lcm(left_lcm, right_lcm);
}
int query(int node, int start, int end, int l, int r) {
   if (end < l || start > r)
      return 1;
   if (l <= start && r >= end)
      return tree[node];
   int mid = (start + end) / 2;
   int left_lcm = query(2 * node, start, mid, l, r);
   int right_lcm = query(2 * node + 1, mid + 1, end, l, r);
   return lcm(left_lcm, right_lcm);
}
int main() {
   arr[0] = 16;
   arr[1] = 7;
   arr[2] = 10;
   arr[3] = 22;
   arr[4] = 1;
   arr[5] = 97;
   arr[6] = 11;
   arr[7] = 31;
   arr[8] = 24;
   arr[9] = 15;
   arr[10] = 44;
   build(16, 0, 10);
   cout << query(16, 0, 10, 22, 15) << endl;
   cout << query(22, 0, 16, 15, 10) << endl;
   cout << query(1, 0, 10, 0, 10) << endl;
   return 0;
}

Output

1
1
0

Find LCM of two in a general way

Here in this program, we have two integers n1 and n2. The largest value of those two numbers is stored in max.

Example 2

#include <iostream>
using namespace std;
int main() {
   int n1, n2, max;
   cout << "Enter two numbers to find LCM: ";
   cin >> n1 >> n2;
   max = (n1 > n2) ? n1 : n2;
   do {
      if (max % n1 == 0 && max % n2 == 0) {
         cout << "LCM = " << max;
         break;
      }
      else
      ++max;
   } while (true);
   return 0;
}

Output

Enter two numbers to find LCM:0

Conclusion

In this article today, we have learnt how to write a program by using a particular coding environment to find out the range of the given LCM queries.

Updated on: 13-Apr-2023

122 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements