Find GCDs of Given Index Ranges in an Array Using C++



In the field of data structure, a range query is a pre-processing method to operate on some input data in an efficient manner. A range query is responsible to answer any query of the particular input on any data subset. If we want to copy some data columns from a table we need to maintain an index for that particular dataset. An index is a direct link or a key, which is designed to provide an efficient searching process in a data set. It is mainly used to speed up the data retrieving from a lost data source.

In mathematics, Greatest Common Divisor aka GCD is a largest possible integer which can divide both of the integers present as the input. Here, all numbers must be present with a non-zero value. Just take an example:

GCD of 70, 80 = 10  (10 is the largest number which divides them with remainder as 0)
GCD of 42, 120, 285 = 3  (3 is the largest number which divides them with remainder as 0)

Algorithm to find the GCDs of given index ranges in an array (in Detailed)

  • Step 1 ? Start

  • Step 2 ? Construct a section of arr[0] to arr[n-1]

  • Step 3 ? Continue the equal partition

  • Step 4 ? Recursive call for these two parts

  • Step 5 ? For each, save only the greatest common divisor value will save in a segment tree

  • Step 6 ? Build another segment tree to fill it from bottom to top

  • Step 7 ? Each node stores some data of GCD with a certain range

  • Step 8 ? If the node range is startQuery and endQuery, then return a value node

  • Step 9 ? Else if, the range is invalid, it will return a null or -1 as output

  • Step 10 ? Else, return a GCD function as a recursive call

  • Step 11 ? Terminate

Algorithm to find the GCDs of given index ranges in an array (in Short) 

  • Step 1 ? Assume, a and b are the two non-zero integers

  • Step 2 ? Let, a mod b = R

  • Step 3 ? If, a=b and b=R

  • Step 4 ? Then, repeat step 2 and step 3

  • Step 5 ? Process will run until a mod b become greater than zero

  • Step 6 ? GCD = b

  • Step 7 ? Terminate

Syntax to find the GCDs of given index ranges in an array

Begin
   if c = 0 OR d = 0, then
      return 0
   if c = d, then
      return b
   if c > d, then
      return findGCD(c-d, d)
   else
      return findGCD(c, d-c)
End

Here in this syntax we can see the possible logic code, how to find the Greatest Common Divisor of two non-zero digits. The time complexity for the process is O(Q*N*log(Ai)) and the auxiliary space is evaluated as O(1).

Approach to follow:-

  • Approach 1 ? Program to find GCD of a number in a given Range using segment Trees

Program to find GCD of a number in a given Range using segment Trees

To find GCD of a number in a given Range using segment Trees, we need to follow some unavoidable steps.

  • Construction of a segment tree:

    • The elements of an input array are the leaf nodes.

    • Each individual internal node represents the GCD of all leaf nodes.

    • Array representation can be done by a segment tree.

      -2*(i+1), index's left element

      -2*(i+2), index's right element

      -Parent is floor((i-1)/2)

  • Construction of a new segment tree by using the given array:

    • Begin the process with a segment arr[0 . . . n-1].

    • Divide them into two halves.

    • Call same for the both halves.

    • Store the value of GCD.

  • Construction of given range for GCD:

    • For every possible query, move the halves of thee tree present left and right.

    • When the given range overlaps on a half; return the node.

    • When it lies outside the given range, return 0 at that moment.

    • For partial overlapping, traverse and get return according the method follows.

Example

#include <bits/stdc++.h>
using namespace std;
int* st;
int findGcd(int ss, int se, int qs, int qe, int si) {
	if (ss > qe || se < qs)
		return 0;
	if (qs <= ss && qe >= se)
		return st[si];
	int mid = ss + (se - ss) / 2;
	return __gcd(findGcd(ss, mid, qs, qe, si * 2 + 1),
				findGcd(mid + 1, se, qs, qe, si * 2 + 2));
}
int findRangeGcd(int ss, int se, int arr[], int n) {
	if (ss < 0 || se > n - 1 || ss > se) {
		cout << "Invalid Arguments"
			<< "\n";
		return -1;
	}
	return findGcd(0, n - 1, ss, se, 0);
}
int constructST(int arr[], int ss, int se, int si) {
	if (ss == se) {
		st[si] = arr[ss];
		return st[si];
	}
	int mid = ss + (se - ss) / 2;
	st[si]
		= __gcd(constructST(arr, ss, mid, si * 2 + 1),
				constructST(arr, mid + 1, se, si * 2 + 2));
	return st[si];
}
int* constructSegmentTree(int arr[], int n) {
	int height = (int)(ceil(log2(n)));
	int size = 2 * (int)pow(2, height) - 1;
	st = new int[size];
	constructST(arr, 0, n - 1, 0);
	return st;
}
int main() {
	int a[] = { 20, 30, 60, 90, 50 };
	int n = sizeof(a) / sizeof(a[0]);
	constructSegmentTree(a, n);
	int l = 1;
	int r = 3;
	cout << "GCD of the given range is here. Please collect your data:";
	cout << findRangeGcd(l, r, a, n) << "\n";

	return 0;
}

Output

GCD of the given range is here. Please collect your data:30

Conclusion

In this article thus, we have developed some possible code by using the particular programming environment. With these encoded logic and the mentioned algorithm we have learned how to find out the GCDs of given index ranges in an array properly.

Updated on: 2023-04-06T15:19:05+05:30

408 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements