# Queries to calculate GCD of an array after multiplying first or last K elements by X

• Last Updated : 06 Aug, 2021

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++

 `// C++ program for the above approach`   `#include ` `using` `namespace` `std;`   `// Function to find the GCD after performing` `// each query on array elements` `void` `findGCDQueries(``int` `arr[], ``int` `N,` `                    ``int` `Queries[][3],` `                    ``int` `Q)` `{` `    ``// Stores prefix array and suffix` `    ``// array` `    ``int` `prefix[N], suffix[N];`   `    ``prefix[0] = arr[0];` `    ``suffix[N - 1] = arr[N - 1];`   `    ``// Build prefix array` `    ``for` `(``int` `i = 1; i < N; i++) {` `        ``prefix[i] = __gcd(prefix[i - 1],` `                          ``arr[i]);` `    ``}`   `    ``// Build suffix array` `    ``for` `(``int` `i = N - 2; i >= 0; i--) {` `        ``suffix[i] = __gcd(suffix[i + 1],` `                          ``arr[i]);` `    ``}`   `    ``// Traverse queries array` `    ``for` `(``int` `i = 0; i < Q; i++) {`   `        ``int` `a = Queries[i][0];` `        ``int` `K = Queries[i][1];` `        ``int` `X = Queries[i][2];`   `        ``// Edge Case when update is` `        ``// is required till the end` `        ``if` `(K == N) {` `            ``cout << prefix[N - 1] * X;` `            ``continue``;` `        ``}`   `        ``// Edge Case when update is` `        ``// is required till the front` `        ``if` `(a == 1) {` `            ``cout << __gcd(prefix[K - 1] * X,` `                          ``suffix[K]);` `        ``}`   `        ``// Find the resultant operation` `        ``// for each query` `        ``else` `{` `            ``cout << __gcd(suffix[N - K] * X,` `                          ``prefix[N - K - 1]);` `        ``}`   `        ``cout << ``" "``;` `    ``}` `}`   `// Driver Code` `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

 `// Java program to implement` `// the above approach` `import` `java.io.*;` `import` `java.util.*;`   `class` `GFG ` `{`   `  ``// Recursive function to return gcd of a and b` `  ``static` `int` `gcd(``int` `a, ``int` `b)` `  ``{`   `    ``// Everything divides 0 ` `    ``if` `(a == ``0``)` `      ``return` `b;` `    ``if` `(b == ``0``)` `      ``return` `a;`   `    ``// base case` `    ``if` `(a == b)` `      ``return` `a;`   `    ``// a is greater` `    ``if` `(a > b)` `      ``return` `gcd(a - b, b);` `    ``return` `gcd(a, b - a);` `  ``}`     `  ``// Function to find the GCD after performing` `  ``// each query on array elements` `  ``static` `void` `findGCDQueries(``int` `arr[], ``int` `N,` `                             ``int` `Queries[][],` `                             ``int` `Q)` `  ``{`   `    ``// Stores prefix array and suffix` `    ``// array` `    ``int` `prefix[] = ``new` `int``[N], suffix[] = ``new` `int``[N];`   `    ``prefix[``0``] = arr[``0``];` `    ``suffix[N - ``1``] = arr[N - ``1``];`   `    ``// Build prefix array` `    ``for` `(``int` `i = ``1``; i < N; i++) {` `      ``prefix[i] = gcd(prefix[i - ``1``],` `                      ``arr[i]);` `    ``}`   `    ``// Build suffix array` `    ``for` `(``int` `i = N - ``2``; i >= ``0``; i--) {` `      ``suffix[i] = gcd(suffix[i + ``1``],` `                      ``arr[i]);` `    ``}`   `    ``// Traverse queries array` `    ``for` `(``int` `i = ``0``; i < Q; i++) {`   `      ``int` `a = Queries[i][``0``];` `      ``int` `K = Queries[i][``1``];` `      ``int` `X = Queries[i][``2``];`   `      ``// Edge Case when update is` `      ``// is required till the end` `      ``if` `(K == N) {` `        ``System.out.print(prefix[N - ``1``] * X);` `        ``continue``;` `      ``}`   `      ``// Edge Case when update is` `      ``// is required till the front` `      ``if` `(a == ``1``) {` `        ``System.out.print(gcd(prefix[K - ``1``] * X,` `                             ``suffix[K]));` `      ``}`   `      ``// Find the resultant operation` `      ``// for each query` `      ``else` `{` `        ``System.out.print(gcd(suffix[N - K] * X,` `                             ``prefix[N - K - ``1``]));` `      ``}`   `      ``System.out.print(``" "``);` `    ``}` `  ``}` `  `  `  ``// Driver Code` `  ``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);` `  ``}` `}`   `// This code is contributed by sanjoy_62.`

## Python3

 `# Python 3 program for the above approach` `from` `math ``import` `gcd`   `# Function to find the GCD after performing` `# each query on array elements` `def` `findGCDQueries(arr, N, Queries, Q):` `  `  `    ``# Stores prefix array and suffix` `    ``# array` `    ``prefix ``=` `[``0` `for` `i ``in` `range``(N)]` `    ``suffix ``=` `[``0` `for` `i ``in` `range``(N)]`   `    ``prefix[``0``] ``=` `arr[``0``]` `    ``suffix[N ``-` `1``] ``=` `arr[N ``-` `1``]`   `    ``# Build prefix array` `    ``for` `i ``in` `range``(``1``,N,``1``):` `        ``prefix[i] ``=` `gcd(prefix[i ``-` `1``], arr[i])`   `    ``# Build suffix array` `    ``i ``=` `N ``-` `2` `    ``while``(i>``=` `0``):` `        ``suffix[i] ``=` `gcd(suffix[i ``+` `1``], arr[i])` `        ``i ``-``=` `1`   `    ``# Traverse queries array` `    ``for` `i ``in` `range``(Q):` `        ``a ``=` `Queries[i][``0``]` `        ``K ``=` `Queries[i][``1``]` `        ``X ``=` `Queries[i][``2``]`   `        ``# Edge Case when update is` `        ``# is required till the end` `        ``if` `(K ``=``=` `N):` `            ``print``(prefix[N ``-` `1``] ``*` `X,end ``=` `" "``)` `            ``continue`   `        ``# Edge Case when update is` `        ``# is required till the front` `        ``if` `(a ``=``=` `1``):` `            ``print``(gcd(prefix[K ``-` `1``] ``*` `X,suffix[K]),end ``=` `" "``)`   `        ``# Find the resultant operation` `        ``# for each query` `        ``else``:` `            ``print``(gcd(suffix[N ``-` `K] ``*` `X, prefix[N ``-` `K ``-` `1``]),end ``=` `" "``)`   `# Driver Code` `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)` `    `  `    ``# This code is contributed by SURENDRA_GANGWAR.`

## C#

 `// C# program to implement` `// the above approach` `using` `System;` `public` `class` `GFG ` `{`   `  ``// Recursive function to return gcd of a and b` `  ``static` `int` `gcd(``int` `a, ``int` `b)` `  ``{`   `    ``// Everything divides 0 ` `    ``if` `(a == 0)` `      ``return` `b;` `    ``if` `(b == 0)` `      ``return` `a;`   `    ``// base case` `    ``if` `(a == b)` `      ``return` `a;`   `    ``// a is greater` `    ``if` `(a > b)` `      ``return` `gcd(a - b, b);` `    ``return` `gcd(a, b - a);` `  ``}`   `  ``// Function to find the GCD after performing` `  ``// each query on array elements` `  ``static` `void` `findGCDQueries(``int` `[]arr, ``int` `N,` `                             ``int` `[,]Queries,` `                             ``int` `Q)` `  ``{`   `    ``// Stores prefix array and suffix` `    ``// array` `    ``int` `[]prefix = ``new` `int``[N];` `    ``int` `[]suffix = ``new` `int``[N];`   `    ``prefix[0] = arr[0];` `    ``suffix[N - 1] = arr[N - 1];`   `    ``// Build prefix array` `    ``for` `(``int` `i = 1; i < N; i++) {` `      ``prefix[i] = gcd(prefix[i - 1],` `                      ``arr[i]);` `    ``}`   `    ``// Build suffix array` `    ``for` `(``int` `i = N - 2; i >= 0; i--) {` `      ``suffix[i] = gcd(suffix[i + 1],` `                      ``arr[i]);` `    ``}`   `    ``// Traverse queries array` `    ``for` `(``int` `i = 0; i < Q; i++) {`   `      ``int` `a = Queries[i,0];` `      ``int` `K = Queries[i,1];` `      ``int` `X = Queries[i,2];`   `      ``// Edge Case when update is` `      ``// is required till the end` `      ``if` `(K == N) {` `        ``Console.Write(prefix[N - 1] * X);` `        ``continue``;` `      ``}`   `      ``// Edge Case when update is` `      ``// is required till the front` `      ``if` `(a == 1) {` `        ``Console.Write(gcd(prefix[K - 1] * X,` `                          ``suffix[K]));` `      ``}`   `      ``// Find the resultant operation` `      ``// for each query` `      ``else` `{` `        ``Console.Write(gcd(suffix[N - K] * X,` `                          ``prefix[N - K - 1]));` `      ``}`   `      ``Console.Write(``" "``);` `    ``}` `  ``}`   `  ``// Driver Code` `  ``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);` `  ``}` `}`   `// This code is contributed by AnkThon.`

## Javascript

 ``

Output

`2 5`

Time Complexity: O((N + Q)* log M), where M is the maximum element of the array.
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up
Related Articles