# Smallest subarray with GCD as 1 | Segment Tree

Given an array arr[], the task is to find the smallest sub-arrays with GCD equal to 1. If there is no such sub-array then print -1.

Examples:

Input: arr[] = {2, 6, 3}
Output: 3
{2, 6, 3} is the only sub-array with GCD = 1.

Input: arr[] = {2, 2, 2}
Output: -1

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Approach: This problem can be solved in O(NlogN) using segment-tree data structure. The segment that will be built can be used to answer range-gcd queries.

Let’s understand the algorithm now. Use the two-pointer technique to solve this problem. Let’s make a few observations before discussing the algorithm.

• Let’s say G is the GCD of the subarray arr[l…r] and G1 is the GCD of the subarray arr[l+1…r]. G smaller than or equal to G1 always.
• Let’s say for the given L1, R1 is the first index such that GCD of the range [L, R] is 1 then for any L2 greater than or equal to L1, R2 will also be greater than or equal to R1.

After the above observation, two-pointer technique makes perfect sense i.e. if the length
of the smallest R is known for an index L then for an index L + 1, the search needs to be started from R on-wards.

Below is the implementation of the above approach:

## C++

 `// C++ implementation of the approach ` `#include ` `using` `namespace` `std; ` `#define maxLen 30 ` ` `  `// Array to store segment-tree ` `int` `seg[3 * maxLen]; ` ` `  `// Function to build segment-tree to ` `// answer range GCD queries ` `int` `build(``int` `l, ``int` `r, ``int` `in, ``int``* arr) ` `{ ` `    ``// Base-case ` `    ``if` `(l == r) ` `        ``return` `seg[in] = arr[l]; ` ` `  `    ``// Mid element of the range ` `    ``int` `mid = (l + r) / 2; ` ` `  `    ``// Merging the result of left and right sub-tree ` `    ``return` `seg[in] = __gcd(build(l, mid, 2 * in + 1, arr), ` `                           ``build(mid + 1, r, 2 * in + 2, arr)); ` `} ` ` `  `// Function to perform range GCD queries ` `int` `query(``int` `l, ``int` `r, ``int` `l1, ``int` `r1, ``int` `in) ` `{ ` `    ``// Base-cases ` `    ``if` `(l1 <= l and r <= r1) ` `        ``return` `seg[in]; ` `    ``if` `(l > r1 or r < l1) ` `        ``return` `0; ` ` `  `    ``// Mid-element ` `    ``int` `mid = (l + r) / 2; ` ` `  `    ``// Calling left and right child ` `    ``return` `__gcd(query(l, mid, l1, r1, 2 * in + 1), ` `                 ``query(mid + 1, r, l1, r1, 2 * in + 2)); ` `} ` ` `  `// Function to find the required length ` `int` `findLen(``int``* arr, ``int` `n) ` `{ ` `    ``// Building the segment tree ` `    ``build(0, n - 1, 0, arr); ` ` `  `    ``// Two pointer variables ` `    ``int` `i = 0, j = 0; ` ` `  `    ``// To store the final answer ` `    ``int` `ans = INT_MAX; ` ` `  `    ``// Looping ` `    ``while` `(i < n) { ` ` `  `        ``// Incrementing j till we don't get ` `        ``// a gcd value of 1 ` `        ``while` `(j < n and query(0, n - 1, i, j, 0) != 1) ` `            ``j++; ` ` `  `        ``if` `(j == n) ` `            ``break``; ` ` `  `        ``// Updating the final answer ` `        ``ans = min((j - i + 1), ans); ` ` `  `        ``// Incrementing i ` `        ``i++; ` ` `  `        ``// Updating j ` `        ``j = max(j, i); ` `    ``} ` ` `  `    ``// Returning the final answer ` `    ``if` `(ans == INT_MAX) ` `        ``return` `-1; ` `    ``else` `        ``return` `ans; ` `} ` ` `  `// Driver code ` `int` `main() ` `{ ` `    ``int` `arr[] = { 2, 2, 2 }; ` `    ``int` `n = ``sizeof``(arr) / ``sizeof``(``int``); ` ` `  `    ``cout << findLen(arr, n); ` ` `  `    ``return` `0; ` `} `

## Java

 `// Java implementation of the approach ` `class` `GFG ` `{ ` `static` `int` `maxLen = ``30``; ` ` `  `// Array to store segment-tree ` `static` `int` `[]seg = ``new` `int``[``3` `* maxLen]; ` ` `  `// Function to build segment-tree to ` `// answer range GCD queries ` `static` `int` `build(``int` `l, ``int` `r,  ` `                 ``int` `in, ``int``[] arr) ` `{ ` `    ``// Base-case ` `    ``if` `(l == r) ` `        ``return` `seg[in] = arr[l]; ` ` `  `    ``// Mid element of the range ` `    ``int` `mid = (l + r) / ``2``; ` ` `  `    ``// Merging the result of left and right sub-tree ` `    ``return` `seg[in] = __gcd(build(l, mid, ``2` `* in + ``1``, arr), ` `                           ``build(mid + ``1``, r, ``2` `* in + ``2``, arr)); ` `} ` ` `  `// Function to perform range GCD queries ` `static` `int` `query(``int` `l, ``int` `r,  ` `                 ``int` `l1, ``int` `r1, ``int` `in) ` `{ ` `    ``// Base-cases ` `    ``if` `(l1 <= l && r <= r1) ` `        ``return` `seg[in]; ` `    ``if` `(l > r1 || r < l1) ` `        ``return` `0``; ` ` `  `    ``// Mid-element ` `    ``int` `mid = (l + r) / ``2``; ` ` `  `    ``// Calling left and right child ` `    ``return` `__gcd(query(l, mid, l1, r1, ``2` `* in + ``1``), ` `                 ``query(mid + ``1``, r, l1, r1, ``2` `* in + ``2``)); ` `} ` ` `  `// Function to find the required length ` `static` `int` `findLen(``int` `[]arr, ``int` `n) ` `{ ` `    ``// Building the segment tree ` `    ``build(``0``, n - ``1``, ``0``, arr); ` ` `  `    ``// Two pointer variables ` `    ``int` `i = ``0``, j = ``0``; ` ` `  `    ``// To store the final answer ` `    ``int` `ans = Integer.MAX_VALUE; ` ` `  `    ``// Looping ` `    ``while` `(i < n) ` `    ``{ ` ` `  `        ``// Incrementing j till we don't get ` `        ``// a gcd value of 1 ` `        ``while` `(j < n && query(``0``, n - ``1``,  ` `                              ``i, j, ``0``) != ``1``) ` `            ``j++; ` ` `  `        ``if` `(j == n) ` `            ``break``; ` ` `  `        ``// Updating the final answer ` `        ``ans = Math.min((j - i + ``1``), ans); ` ` `  `        ``// Incrementing i ` `        ``i++; ` ` `  `        ``// Updating j ` `        ``j = Math.max(j, i); ` `    ``} ` ` `  `    ``// Returning the final answer ` `    ``if` `(ans == Integer.MAX_VALUE) ` `        ``return` `-``1``; ` `    ``else` `        ``return` `ans; ` `} ` ` `  `static` `int` `__gcd(``int` `a, ``int` `b)  ` `{  ` `    ``return` `b == ``0` `? a : __gcd(b, a % b);      ` `}  ` ` `  `// Driver code ` `public` `static` `void` `main(String[] args) ` `{ ` `    ``int` `arr[] = { ``2``, ``2``, ``2` `}; ` `    ``int` `n = arr.length; ` ` `  `    ``System.out.println(findLen(arr, n)); ` `} ` `} ` ` `  `// This code is contributed by 29AjayKumar `

## Python3

 `# Python3 implementation of the approach ` `from` `math ``import` `gcd as __gcd ` ` `  `maxLen ``=` `30` ` `  `# Array to store segment-tree ` `seg ``=` `[``0` `for` `i ``in` `range``(``3` `*` `maxLen)] ` ` `  `# Function to build segment-tree to ` `# answer range GCD queries ` `def` `build(l, r, inn, arr): ` `     `  `    ``# Base-case ` `    ``if` `(l ``=``=` `r): ` `        ``seg[inn] ``=` `arr[l] ` `        ``return` `seg[inn] ` ` `  `    ``# Mid element of the range ` `    ``mid ``=` `(l ``+` `r) ``/``/` `2` ` `  `    ``# Merging the result of  ` `    ``# left and right sub-tree ` `    ``seg[inn] ``=` `__gcd(build(l, mid, ` `                           ``2` `*` `inn ``+` `1``, arr),  ` `                     ``build(mid ``+` `1``, r,  ` `                           ``2` `*` `inn ``+` `2``, arr)) ` ` `  `    ``return` `seg[inn] ` ` `  `# Function to perform range GCD queries ` `def` `query(l, r, l1, r1, inn): ` `     `  `    ``# Base-cases ` `    ``if` `(l1 <``=` `l ``and` `r <``=` `r1): ` `        ``return` `seg[inn] ` `    ``if` `(l > r1 ``or` `r < l1): ` `        ``return` `0` ` `  `    ``# Mid-element ` `    ``mid ``=` `(l ``+` `r) ``/``/` `2` ` `  `    ``# Calling left and right child ` `    ``x``=``__gcd(query(l, mid, l1, r1, ` `                  ``2` `*` `inn ``+` `1``),  ` `            ``query(mid ``+` `1``, r, l1, r1, ` `                  ``2` `*` `inn ``+` `2``)) ` `    ``return` `x ` ` `  `# Function to find the required length ` `def` `findLen(arr, n): ` `     `  `    ``# Buildinng the segment tree ` `    ``build(``0``, n ``-` `1``, ``0``, arr) ` ` `  `    ``# Two pointer variables ` `    ``i ``=` `0` `    ``j ``=` `0` ` `  `    ``# To store the finnal answer ` `    ``ans ``=` `10``*``*``9` ` `  `    ``# Loopinng ` `    ``while` `(i < n): ` ` `  `        ``# Incrementinng j till we  ` `        ``# don't get a gcd value of 1 ` `        ``while` `(j < n ``and` `query(``0``, n ``-` `1``, ` `                               ``i, j, ``0``) !``=` `1``): ` `            ``j ``+``=` `1` ` `  `        ``if` `(j ``=``=` `n): ` `            ``break``; ` ` `  `        ``# Updatinng the finnal answer ` `        ``ans ``=` `minn((j ``-` `i ``+` `1``), ans) ` ` `  `        ``# Incrementinng i ` `        ``i ``+``=` `1` ` `  `        ``# Updatinng j ` `        ``j ``=` `max``(j, i) ` ` `  `    ``# Returninng the finnal answer ` `    ``if` `(ans ``=``=` `10``*``*``9``): ` `        ``return` `-``1` `    ``else``: ` `        ``return` `ans ` ` `  `# Driver code ` `arr ``=` `[``2``, ``2``, ``2``] ` `n ``=` `len``(arr) ` ` `  `print``(findLen(arr, n)) ` ` `  `# This code is contributed by Mohit Kumar `

## C#

 `// C# implementation of the approach ` `using` `System; ` ` `  `class` `GFG ` `{ ` `    ``static` `int` `maxLen = 30; ` `     `  `    ``// Array to store segment-tree ` `    ``static` `int` `[]seg = ``new` `int``[3 * maxLen]; ` `     `  `    ``// Function to build segment-tree to ` `    ``// answer range GCD queries ` `    ``static` `int` `build(``int` `l, ``int` `r,  ` `                     ``int` `ind, ``int``[] arr) ` `    ``{ ` `        ``// Base-case ` `        ``if` `(l == r) ` `            ``return` `seg[ind] = arr[l]; ` `     `  `        ``// Mid element of the range ` `        ``int` `mid = (l + r) / 2; ` `     `  `        ``// Merging the result of left and right sub-tree ` `        ``return` `seg[ind] = __gcd(build(l, mid, 2 * ind + 1, arr), ` `                                ``build(mid + 1, r, 2 * ind + 2, arr)); ` `    ``} ` `     `  `    ``// Function to perform range GCD queries ` `    ``static` `int` `query(``int` `l, ``int` `r,  ` `                     ``int` `l1, ``int` `r1, ``int` `ind) ` `    ``{ ` `        ``// Base-cases ` `        ``if` `(l1 <= l && r <= r1) ` `            ``return` `seg[ind]; ` `        ``if` `(l > r1 || r < l1) ` `            ``return` `0; ` `     `  `        ``// Mid-element ` `        ``int` `mid = (l + r) / 2; ` `     `  `        ``// Calling left and right child ` `        ``return` `__gcd(query(l, mid, l1, r1, 2 * ind + 1), ` `                     ``query(mid + 1, r, l1, r1, 2 * ind + 2)); ` `    ``} ` `     `  `    ``// Function to find the required length ` `    ``static` `int` `findLen(``int` `[]arr, ``int` `n) ` `    ``{ ` `        ``// Building the segment tree ` `        ``build(0, n - 1, 0, arr); ` `     `  `        ``// Two pointer variables ` `        ``int` `i = 0, j = 0; ` `     `  `        ``// To store the final answer ` `        ``int` `ans = ``int``.MaxValue; ` `     `  `        ``// Looping ` `        ``while` `(i < n) ` `        ``{ ` `     `  `            ``// Incrementing j till we don't get ` `            ``// a gcd value of 1 ` `            ``while` `(j < n && query(0, n - 1,  ` `                                  ``i, j, 0) != 1) ` `                ``j++; ` `     `  `            ``if` `(j == n) ` `                ``break``; ` `     `  `            ``// Updating the final answer ` `            ``ans = Math.Min((j - i + 1), ans); ` `     `  `            ``// Incrementing i ` `            ``i++; ` `     `  `            ``// Updating j ` `            ``j = Math.Max(j, i); ` `        ``} ` `     `  `        ``// Returning the final answer ` `        ``if` `(ans == ``int``.MaxValue) ` `            ``return` `-1; ` `        ``else` `            ``return` `ans; ` `    ``} ` `     `  `    ``static` `int` `__gcd(``int` `a, ``int` `b)  ` `    ``{  ` `        ``return` `b == 0 ? a : __gcd(b, a % b);      ` `    ``}  ` `     `  `    ``// Driver code ` `    ``public` `static` `void` `Main() ` `    ``{ ` `        ``int` `[]arr = { 2, 2, 2 }; ` `        ``int` `n = arr.Length; ` `     `  `        ``Console.WriteLine(findLen(arr, n)); ` `    ``} ` `} ` ` `  `// This code is contributed by kanugargng `

Output:

```-1
```

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.