Skip to content

# Queries to find the length of the longest prefix from given array having all elements divisible by K

• Difficulty Level : Easy
• Last Updated : 26 Nov, 2021

Given an array arr[] consisting of N elements and an arrayQ[], the task for each query is to find the length of the longest prefix such that all the elements of this prefix are divisible by K.

Examples:

Input: arr[] = {12, 6, 15, 3, 10}, Q[] = {4, 3, 2}
Output: 1 4 2
Explanation:

• Q[0] = 4: arr[0] (= 12) is divisible by 4. arr[1] is not divisible by 4. Therefore, the length of the longest prefix divisible by 4 is 1.
• Q[1] = 3: The longest prefix which is divisible by 3 is {12, 6, 15, 3}. Therefore, print 4 as the required output.
• Q[2] = 2: The longest prefix which is divisible by 2 is {12, 6}.

Input: arr[] = {4, 3, 2, 1}, Q[] = {1, 2, 3}
Output: 4 1 0

Approach: The idea is to observe that if the first i elements of the array are divisible by the given integer K, then their GCD will also be divisible by K. Follow the steps below to solve the problem:

1. Before finding the answer to each query, pre-compute the gcd of the prefixes of the array in another array g[] such that g[0] = arr[0] and for the rest of the elements g[i] = GCD(arr[i], g[i – 1]).
2. Then, for each element in the array Q[], perform Binary Search on the array g[] and find the last index of g[] which is divisible by Q[i].
3. It has to be noted that all the elements in this index will be divisible by K, since the gcd of all the elements till this index is divisible by K.
4. Print the length of the longest prefix.

Below is the implementation of the above approach.

## C++

 `// C++ program for the above approach`   `#include ` `using` `namespace` `std;`   `// Function to find index of the last` `// element which is divisible the given element` `int` `binSearch(``int``* g, ``int` `st, ``int` `en, ``int` `val)` `{` `    ``// Initially assume the` `    ``// index to be -1` `    ``int` `ind = -1;` `    ``while` `(st <= en) {`   `        ``// Find the mid element` `        ``// of the subarray` `        ``int` `mid = st + (en - st) / 2;`   `        ``// If the mid element is divisible by` `        ``// given element, then move to right` `        ``// of mid and update ind to mid` `        ``if` `(g[mid] % val == 0) {` `            ``ind = mid;` `            ``st = mid + 1;` `        ``}`   `        ``// Otherwise, move to left of mid` `        ``else` `{` `            ``en = mid - 1;` `        ``}` `    ``}`   `    ``// Return the length of prefix` `    ``return` `ind + 1;` `}`   `// Function to compute and print for each query` `void` `solveQueries(``int``* arr, ``int``* queries,` `                  ``int` `n, ``int` `q)` `{` `    ``int` `g[n];`   `    ``// Pre compute the gcd of the prefixes` `    ``// of the input array in the array g[]` `    ``for` `(``int` `i = 0; i < n; i++) {` `        ``if` `(i == 0) {` `            ``g[i] = arr[i];` `        ``}` `        ``else` `{` `            ``g[i] = __gcd(g[i - 1], arr[i]);` `        ``}` `    ``}`   `    ``// Perform binary search` `    ``// for each query` `    ``for` `(``int` `i = 0; i < q; i++) {` `        ``cout << binSearch(g, 0, n - 1,` `                          ``queries[i])` `             ``<< ``" "``;` `    ``}` `}`   `// Driver Code` `int` `main()` `{` `    ``// Given array` `    ``int` `arr[] = { 12, 6, 15, 3, 10 };`   `    ``// Size of array` `    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr[0]);`   `    ``// Given Queries` `    ``int` `queries[] = { 4, 3, 2 };`   `    ``// Size of queries` `    ``int` `q = ``sizeof``(queries) / ``sizeof``(queries[0]);`   `    ``solveQueries(arr, queries, n, q);` `}`

## Java

 `// Java program for the above approach` `import` `java.util.*;` `class` `GFG` `{`   `// Function to find index of the last` `// element which is divisible the given element` `static` `int` `binSearch(``int``[] g, ``int` `st, ``int` `en, ``int` `val)` `{` `  `  `    ``// Initially assume the` `    ``// index to be -1` `    ``int` `ind = -``1``;` `    ``while` `(st <= en)` `    ``{`   `        ``// Find the mid element` `        ``// of the subarray` `        ``int` `mid = st + (en - st) / ``2``;`   `        ``// If the mid element is divisible by` `        ``// given element, then move to right` `        ``// of mid and update ind to mid` `        ``if` `(g[mid] % val == ``0``) ` `        ``{` `            ``ind = mid;` `            ``st = mid + ``1``;` `        ``}`   `        ``// Otherwise, move to left of mid` `        ``else` `        ``{` `            ``en = mid - ``1``;` `        ``}` `    ``}`   `    ``// Return the length of prefix` `    ``return` `ind + ``1``;` `}`   `// Function to compute and print for each query` `static` `void` `solveQueries(``int` `[]arr, ``int` `[]queries,` `                  ``int` `n, ``int` `q)` `{` `    ``int` `[]g = ``new` `int``[n];`   `    ``// Pre compute the gcd of the prefixes` `    ``// of the input array in the array g[]` `    ``for` `(``int` `i = ``0``; i < n; i++)` `    ``{` `        ``if` `(i == ``0``) {` `            ``g[i] = arr[i];` `        ``}` `        ``else` `{` `            ``g[i] = __gcd(g[i - ``1``], arr[i]);` `        ``}` `    ``}`   `    ``// Perform binary search` `    ``// for each query` `    ``for` `(``int` `i = ``0``; i < q; i++)` `    ``{` `        ``System.out.print(binSearch(g, ``0``, n - ``1``,` `                          ``queries[i])` `            ``+ ``" "``);` `    ``}` `}` `static` `int` `__gcd(``int` `a, ``int` `b)  ` `{  ` `    ``return` `b == ``0``? a:__gcd(b, a % b);     ` `}` `  `  `// Driver Code` `public` `static` `void` `main(String[] args)` `{` `  `  `    ``// Given array` `    ``int` `arr[] = { ``12``, ``6``, ``15``, ``3``, ``10` `};`   `    ``// Size of array` `    ``int` `n = arr.length;`   `    ``// Given Queries` `    ``int` `queries[] = { ``4``, ``3``, ``2` `};`   `    ``// Size of queries` `    ``int` `q = queries.length;` `    ``solveQueries(arr, queries, n, q);` `}` `}`   `// This code is contributed by 29AjayKumar`

## Python3

 `# Python3 program for the above approach` `from` `math ``import` `gcd as __gcd`   `# Function to find index of the last` `# element which is divisible the ` `# given element` `def` `binSearch(g, st, en, val):` `    `  `    ``# Initially assume the` `    ``# index to be -1` `    ``ind ``=` `-``1` `    `  `    ``while` `(st <``=` `en):`   `        ``# Find the mid element` `        ``# of the subarray` `        ``mid ``=` `st ``+` `(en ``-` `st) ``/``/` `2`   `        ``# If the mid element is divisible by` `        ``# given element, then move to right` `        ``# of mid and update ind to mid` `        ``if` `(g[mid] ``%` `val ``=``=` `0``):` `            ``ind ``=` `mid` `            ``st ``=` `mid ``+` `1`   `        ``# Otherwise, move to left of mid` `        ``else``:` `            ``en ``=` `mid ``-` `1`   `    ``# Return the length of prefix` `    ``return` `ind ``+` `1`   `# Function to compute and print for each query` `def` `solveQueries(arr, queries, n, q):` `    `  `    ``g ``=` `[``0` `for` `i ``in` `range``(n)]`   `    ``# Pre compute the gcd of the prefixes` `    ``# of the input array in the array g[]` `    ``for` `i ``in` `range``(n):` `        ``if` `(i ``=``=` `0``):` `            ``g[i] ``=` `arr[i]` `        ``else``:` `            ``g[i] ``=` `__gcd(g[i ``-` `1``], arr[i])`   `    ``# Perform binary search` `    ``# for each query` `    ``for` `i ``in` `range``(q):` `        ``print``(binSearch(g, ``0``, n ``-` `1``, ` `                        ``queries[i]), end ``=` `" "``)`   `# Driver Code` `if` `__name__ ``=``=` `'__main__'``:` `    `  `    ``# Given array` `    ``arr ``=` `[ ``12``, ``6``, ``15``, ``3``, ``10` `]`   `    ``# Size of array` `    ``n ``=` `len``(arr)`   `    ``# Given Queries` `    ``queries ``=` `[ ``4``, ``3``, ``2` `]`   `    ``# Size of queries` `    ``q ``=` `len``(queries)`   `    ``solveQueries(arr, queries, n, q)`   `# This code is contributed by mohit kumar 29`

## C#

 `// C# program to implement` `// the above approach  ` `using` `System; ` `class` `GFG` `{` ` `  `// Function to find index of the last` `// element which is divisible the given element` `static` `int` `binSearch(``int``[] g, ``int` `st, ``int` `en, ``int` `val)` `{` `  `  `  ``// Initially assume the` `  ``// index to be -1` `  ``int` `ind = -1;` `  ``while` `(st <= en) ` `  ``{`   `    ``// Find the mid element` `    ``// of the subarray` `    ``int` `mid = st + (en - st) / 2;`   `    ``// If the mid element is divisible by` `    ``// given element, then move to right` `    ``// of mid and update ind to mid` `    ``if` `(g[mid] % val == 0) ` `    ``{` `      ``ind = mid;` `      ``st = mid + 1;` `    ``}`   `    ``// Otherwise, move to left of mid` `    ``else` `    ``{` `      ``en = mid - 1;` `    ``}` `  ``}`   `  ``// Return the length of prefix` `  ``return` `ind + 1;` `}`   `  ``// 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 compute and print for each query` `  ``static` `void` `solveQueries(``int``[] arr, ``int``[] queries,` `                           ``int` `n, ``int` `q)` `  ``{` `    ``int``[] g = ``new` `int``[n];`   `    ``// Pre compute the gcd of the prefixes` `    ``// of the input array in the array g[]` `    ``for` `(``int` `i = 0; i < n; i++) ` `    ``{` `      ``if` `(i == 0)` `      ``{` `        ``g[i] = arr[i];` `      ``}` `      ``else` `      ``{` `        ``g[i] = gcd(g[i - 1], arr[i]);` `      ``}` `    ``}`   `    ``// Perform binary search` `    ``// for each query` `    ``for` `(``int` `i = 0; i < q; i++) ` `    ``{` `      ``Console.Write(binSearch(g, 0, n - 1,` `                              ``queries[i]) + ``" "``);` `    ``}` `  ``}` ` `  `// Driver code` `public` `static` `void` `Main()` `{` `  `  `    ``// Given array` `    ``int``[] arr = { 12, 6, 15, 3, 10 };` ` `  `    ``// Size of array` `    ``int` `n = arr.Length;` ` `  `    ``// Given Queries` `    ``int``[] queries = { 4, 3, 2 };` ` `  `    ``// Size of queries` `    ``int` `q = queries.Length; ` `    ``solveQueries(arr, queries, n, q);` `}` `}`   `// This code is contributed by susmitakundugoaldanga`

## Javascript

 ``

Output:

`1 4 2`

Time Complexity: O(NlogN + QlogN)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up
Recommended Articles
Page :