Queries to calculate GCD of an array after multiplying first or last K elements by X
Given an array arr[] consisting of N positive integers and a 2D array queries[][] of the type {a, K, X} such that if the value of a is 1, then multiply first K array elements by X. Otherwise, multiply last K array elements by X. The task is to calculate GCD of the array after performing each query on the original array.
Examples:
Input: arr[] = {2, 3, 4, 8}, Queries[][3] = {{1, 2, 2}, {2, 4, 5}}
Output: 2 5
Explanation:
Query 1: The given query is {1, 2, 2}. After multiplying the first 2 array elements by 2, arr[] modifies to {4, 6, 4, 8}. GCD of the modified array is 2.
Query 2: The given query is {2, 4, 5}. After multiplying the last 4 elements array elements by 5, arr[] modifies to {10, 15, 20, 40}. GCD of the updated array is 5.
Input: arr[] = {4, 12, 4, 9}, Queries[][3] = {{1, 3, 3}, {2, 4, 1}}
Output: 3 1
Naive Approach: The simplest approach is to update the given array by performing each query and then find the GCD of the updated array.
Time Complexity: O(N * Q * log(M)), where M is the maximum element present in the array.
Auxiliary Space: O(N)
Efficient Approach: The above approach can be optimized by storing the prefix and suffix GCD arrays of the given array and solving each query in O(1) time by following the below steps:
- Initialize an array prefix[] and suffix[] of size N to store the prefix and suffix GCD arrays of the given array.
- Traverse the array from the front and the back and find the prefix and suffix GCD at each index and store it in prefix[] and suffix[] respectively.
- Now, traverse the array queries[] and for each query {a, K, X} perform the following:
- If the value of K is N then print the value of prefix[N – 1] * X as the result.
- If the value of a is 1, then find the GCD of prefix[K – 1] * X and suffix[K] as the result as the prefix[K – 1] * X is the new GCD of first K numbers and suffix[K + 1] is the GCD of the remaining array elements.
- If the value of a is 2, then find the GCD of prefix[N – K – 1] and suffix[N – K] * X as the result as the prefix[N – K – 1] * X is the new GCD of first K numbers and suffix[N – K] is the GCD of the remaining array elements.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void findGCDQueries( int arr[], int N,
int Queries[][3],
int Q)
{
int prefix[N], suffix[N];
prefix[0] = arr[0];
suffix[N - 1] = arr[N - 1];
for ( int i = 1; i < N; i++) {
prefix[i] = __gcd(prefix[i - 1],
arr[i]);
}
for ( int i = N - 2; i >= 0; i--) {
suffix[i] = __gcd(suffix[i + 1],
arr[i]);
}
for ( int i = 0; i < Q; i++) {
int a = Queries[i][0];
int K = Queries[i][1];
int X = Queries[i][2];
if (K == N) {
cout << prefix[N - 1] * X;
continue ;
}
if (a == 1) {
cout << __gcd(prefix[K - 1] * X,
suffix[K]);
}
else {
cout << __gcd(suffix[N - K] * X,
prefix[N - K - 1]);
}
cout << " " ;
}
}
int main()
{
int arr[] = { 2, 3, 4, 8 };
int N = sizeof (arr) / sizeof (arr[0]);
int Queries[][3] = {
{ 1, 2, 2 },
{ 2, 4, 5 }
};
int Q = sizeof (Queries)
/ sizeof (Queries[0]);
findGCDQueries(arr, N, Queries, Q);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG
{
static int gcd( int a, int b)
{
if (a == 0 )
return b;
if (b == 0 )
return a;
if (a == b)
return a;
if (a > b)
return gcd(a - b, b);
return gcd(a, b - a);
}
static void findGCDQueries( int arr[], int N,
int Queries[][],
int Q)
{
int prefix[] = new int [N], suffix[] = new int [N];
prefix[ 0 ] = arr[ 0 ];
suffix[N - 1 ] = arr[N - 1 ];
for ( int i = 1 ; i < N; i++) {
prefix[i] = gcd(prefix[i - 1 ],
arr[i]);
}
for ( int i = N - 2 ; i >= 0 ; i--) {
suffix[i] = gcd(suffix[i + 1 ],
arr[i]);
}
for ( int i = 0 ; i < Q; i++) {
int a = Queries[i][ 0 ];
int K = Queries[i][ 1 ];
int X = Queries[i][ 2 ];
if (K == N) {
System.out.print(prefix[N - 1 ] * X);
continue ;
}
if (a == 1 ) {
System.out.print(gcd(prefix[K - 1 ] * X,
suffix[K]));
}
else {
System.out.print(gcd(suffix[N - K] * X,
prefix[N - K - 1 ]));
}
System.out.print( " " );
}
}
public static void main(String[] args)
{
int arr[] = { 2 , 3 , 4 , 8 };
int N = arr.length;
int Queries[][] = {
{ 1 , 2 , 2 },
{ 2 , 4 , 5 }
};
int Q = Queries.length;
findGCDQueries(arr, N, Queries, Q);
}
}
|
Python3
from math import gcd
def findGCDQueries(arr, N, Queries, Q):
prefix = [ 0 for i in range (N)]
suffix = [ 0 for i in range (N)]
prefix[ 0 ] = arr[ 0 ]
suffix[N - 1 ] = arr[N - 1 ]
for i in range ( 1 ,N, 1 ):
prefix[i] = gcd(prefix[i - 1 ], arr[i])
i = N - 2
while (i> = 0 ):
suffix[i] = gcd(suffix[i + 1 ], arr[i])
i - = 1
for i in range (Q):
a = Queries[i][ 0 ]
K = Queries[i][ 1 ]
X = Queries[i][ 2 ]
if (K = = N):
print (prefix[N - 1 ] * X,end = " " )
continue
if (a = = 1 ):
print (gcd(prefix[K - 1 ] * X,suffix[K]),end = " " )
else :
print (gcd(suffix[N - K] * X, prefix[N - K - 1 ]),end = " " )
if __name__ = = '__main__' :
arr = [ 2 , 3 , 4 , 8 ]
N = len (arr)
Queries = [[ 1 , 2 , 2 ], [ 2 , 4 , 5 ]]
Q = len (Queries)
findGCDQueries(arr, N, Queries, Q)
|
C#
using System;
public class GFG
{
static int gcd( int a, int b)
{
if (a == 0)
return b;
if (b == 0)
return a;
if (a == b)
return a;
if (a > b)
return gcd(a - b, b);
return gcd(a, b - a);
}
static void findGCDQueries( int []arr, int N,
int [,]Queries,
int Q)
{
int []prefix = new int [N];
int []suffix = new int [N];
prefix[0] = arr[0];
suffix[N - 1] = arr[N - 1];
for ( int i = 1; i < N; i++) {
prefix[i] = gcd(prefix[i - 1],
arr[i]);
}
for ( int i = N - 2; i >= 0; i--) {
suffix[i] = gcd(suffix[i + 1],
arr[i]);
}
for ( int i = 0; i < Q; i++) {
int a = Queries[i,0];
int K = Queries[i,1];
int X = Queries[i,2];
if (K == N) {
Console.Write(prefix[N - 1] * X);
continue ;
}
if (a == 1) {
Console.Write(gcd(prefix[K - 1] * X,
suffix[K]));
}
else {
Console.Write(gcd(suffix[N - K] * X,
prefix[N - K - 1]));
}
Console.Write( " " );
}
}
public static void Main( string [] args)
{
int []arr = { 2, 3, 4, 8 };
int N = arr.Length;
int [,]Queries = {
{ 1, 2, 2 },
{ 2, 4, 5 }
};
int Q = Queries.GetLength(0);
findGCDQueries(arr, N, Queries, Q);
}
}
|
Javascript
<script>
function gcd(a, b)
{
if (a == 0)
return b;
if (b == 0)
return a;
if (a == b)
return a;
if (a > b)
return gcd(a - b, b);
return gcd(a, b - a);
}
function findGCDQueries(arr, N, Queries, Q)
{
let prefix = new Array(N), suffix = new Array(N);
prefix[0] = arr[0];
suffix[N - 1] = arr[N - 1];
for (let i = 1; i < N; i++) {
prefix[i] = gcd(prefix[i - 1],
arr[i]);
}
for (let i = N - 2; i >= 0; i--) {
suffix[i] = gcd(suffix[i + 1],
arr[i]);
}
for (let i = 0; i < Q; i++) {
let a = Queries[i][0];
let K = Queries[i][1];
let X = Queries[i][2];
if (K == N) {
document.write(prefix[N - 1] * X);
continue ;
}
if (a == 1) {
document.write(gcd(prefix[K - 1] * X,
suffix[K]));
}
else {
document.write(gcd(suffix[N - K] * X,
prefix[N - K - 1]));
}
document.write( " " );
}
}
let arr = [ 2, 3, 4, 8 ];
let N = arr.length;
let Queries = [
[ 1, 2, 2 ],
[ 2, 4, 5 ]
];
let Q = Queries.length;
findGCDQueries(arr, N, Queries, Q);
</script>
|
Time Complexity: O((N + Q)* log M), where M is the maximum element of the array.
Auxiliary Space: O(N)
Last Updated :
06 Aug, 2021
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...