# Make Binary Search Tree

Given an array arr[] of size N. The task is to find whether it is possible to make Binary Search Tree with the given array of elements such that greatest common divisor of any two vertices connected by a common edge is > 1. If possible then print Yes else print No.

Examples:

Input: arr[] = {3, 6, 9, 18, 36, 108}
Output: Yes

This is one of the possible Binary Search Tree with given array.

Input: arr[] = {2, 17}
Output: No

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

Approach: Let DP(l, r, root) be a DP determining whether it’s possible to assemble a tree rooted at root from the sub-segment [l..r].
It’s easy to see that calculating it requires extracting such rootleft from [l..root – 1] and rootright from [root + 1..right] such that:

• gcd(aroot, arootleft) > 1
• gcd(aroot, arootright) > 1
• DP(l, root-1, rootleft) = 1
• DP(root+1, r, rootright) = 1

This can be done in O(r – l) provided we are given all DP(x, y, z) values for all sub-segments of [l..r]. Considering a total of O(n3) DP states, the final complexity is O(n4) and that’s too much.

Let’s turn our DP into DPnew(l, r, state) where the state can be either 0 or 1. It immediately turns out that DP(l, r, root) is inherited from DPnew(l, root-1, 1) and DPnew(root+1, r, 0). Now we have O(n2) states, but at the same time, all transitions are performed in linear time. Thus final complexity is O(n3) which is sufficient to pass.

Below is the implementation of the above approach:

## C++

 `// C++ implementation of the appraoch ` `#include ` `using` `namespace` `std; ` ` `  `// Maxium number of vertices ` `#define N 705 ` ` `  `// To store is it possible at ` `// particular pace or not ` `int` `dp[N][N][2]; ` ` `  `// Return 1 if from l to r, it is possible with ` `// the given state ` `int` `possibleWithState(``int` `l, ``int` `r, ``int` `state, ``int` `a[]) ` `{ ` `    ``// Base condition ` `    ``if` `(l > r) ` `        ``return` `1; ` ` `  `    ``// If it is already calculated ` `    ``if` `(dp[l][r][state] != -1) ` `        ``return` `dp[l][r][state]; ` ` `  `    ``// Choose the root ` `    ``int` `root; ` `    ``if` `(state == 1) ` `        ``root = a[r + 1]; ` `    ``else` `        ``root = a[l - 1]; ` ` `  `    ``// Traverse in range l to r ` `    ``for` `(``int` `i = l; i <= r; i++) { ` ` `  `        ``// If gcd is greater than one ` `        ``// check for both sides ` `        ``if` `(__gcd(a[i], root) > 1) { ` `            ``int` `x = possibleWithState(l, i - 1, 1, a); ` `            ``if` `(x != 1) ` `                ``continue``; ` `            ``int` `y = possibleWithState(i + 1, r, 0, a); ` `            ``if` `(x == 1 && y == 1) ` `                ``return` `dp[l][r][state] = 1; ` `        ``} ` `    ``} ` ` `  `    ``// If not possible ` `    ``return` `dp[l][r][state] = 0; ` `} ` ` `  `// Function that return true if it is possible ` `// to make Binary Search Tree ` `bool` `isPossible(``int` `a[], ``int` `n) ` `{ ` `    ``memset``(dp, -1, ``sizeof` `dp); ` ` `  `    ``// Sort the given array ` `    ``sort(a, a + n); ` ` `  `    ``// Check it is possible rooted at i ` `    ``for` `(``int` `i = 0; i < n; i++) ` ` `  `        ``// Check at both sides ` `        ``if` `(possibleWithState(0, i - 1, 1, a) ` `            ``&& possibleWithState(i + 1, n - 1, 0, a)) { ` `            ``return` `true``; ` `        ``} ` ` `  `    ``return` `false``; ` `} ` ` `  `// Driver code ` `int` `main() ` `{ ` `    ``int` `a[] = { 3, 6, 9, 18, 36, 108 }; ` `    ``int` `n = ``sizeof``(a) / ``sizeof``(a[0]); ` ` `  `    ``if` `(isPossible(a, n)) ` `        ``cout << ``"Yes"``; ` `    ``else` `        ``cout << ``"No"``; ` ` `  `    ``return` `0; ` `} `

## Java

 `// Java implementation of the approach ` `import` `java.util.*; ` `class` `GFG ` `{ ` `     `  `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);  ` `}  ` ` `  `// Maxium number of vertices ` `static` `final` `int` `N = ``705``; ` ` `  `// To store is it possible at ` `// particular pace or not ` `static` `int` `dp[][][] = ``new` `int``[N][N][``2``]; ` ` `  `// Return 1 if from l to r, it is  ` `// possible with the given state ` `static` `int` `possibleWithState(``int` `l, ``int` `r, ` `                        ``int` `state, ``int` `a[]) ` `{ ` `    ``// Base condition ` `    ``if` `(l > r) ` `        ``return` `1``; ` ` `  `    ``// If it is already calculated ` `    ``if` `(dp[l][r][state] != -``1``) ` `        ``return` `dp[l][r][state]; ` ` `  `    ``// Choose the root ` `    ``int` `root; ` `    ``if` `(state == ``1``) ` `        ``root = a[r + ``1``]; ` `    ``else` `        ``root = a[l - ``1``]; ` ` `  `    ``// Traverse in range l to r ` `    ``for` `(``int` `i = l; i <= r; i++)  ` `    ``{ ` ` `  `        ``// If gcd is greater than one ` `        ``// check for both sides ` `        ``if` `(__gcd(a[i], root) > ``1``)  ` `        ``{ ` `            ``int` `x = possibleWithState(l, i - ``1``, ``1``, a); ` `            ``if` `(x != ``1``) ` `                ``continue``; ` `                 `  `            ``int` `y = possibleWithState(i + ``1``, r, ``0``, a); ` `             `  `            ``if` `(x == ``1` `&& y == ``1``) ` `                ``return` `dp[l][r][state] = ``1``; ` `        ``} ` `    ``} ` ` `  `    ``// If not possible ` `    ``return` `dp[l][r][state] = ``0``; ` `} ` ` `  `// Function that return true if it is possible ` `// to make Binary Search Tree ` `static` `boolean` `isPossible(``int` `a[], ``int` `n) ` `{ ` `    ``for``(``int` `i = ``0``; i < dp.length; i++) ` `        ``for``(``int` `j = ``0``; j < dp[i].length; j++) ` `            ``for``(``int` `k = ``0``; k < dp[i][j].length; k++) ` `                ``dp[i][j][k]=-``1``; ` ` `  `    ``// Sort the given array ` `    ``Arrays.sort(a); ` ` `  `    ``// Check it is possible rooted at i ` `    ``for` `(``int` `i = ``0``; i < n; i++) ` ` `  `        ``// Check at both sides ` `        ``if` `(possibleWithState(``0``, i - ``1``, ``1``, a) != ``0` `&&  ` `            ``possibleWithState(i + ``1``, n - ``1``, ``0``, a) != ``0``) ` `        ``{ ` `            ``return` `true``; ` `        ``} ` ` `  `    ``return` `false``; ` `} ` ` `  `// Driver code ` `public` `static` `void` `main(String args[]) ` `{ ` `    ``int` `a[] = { ``3``, ``6``, ``9``, ``18``, ``36``, ``108` `}; ` `    ``int` `n = a.length; ` ` `  `    ``if` `(isPossible(a, n)) ` `        ``System.out.println(``"Yes"``); ` `    ``else` `        ``System.out.println(``"No"``); ` ` `  `} ` `} ` ` `  `// This code is contributed by  ` `// Arnab Kundu `

## Python3

# Python3 implementation of the appraoch
import math

# Maxium number of vertices
N = 705

# To store is it possible at
# particular pace or not
dp = [[[-1 for z in range(2)]
for x in range(N)]
for y in range(N)]

# Return 1 if from l to r, it is
# possible with the given state
def possibleWithState(l, r, state, a):

# Base condition
if (l > r):
return 1

# If it is already calculated
if (dp[l][r][state] != -1):
return dp[l][r][state]

# Choose the root
root = 0
if (state == 1) :
root = a[r + 1]
else:
root = a[l – 1]

# Traverse in range l to r
for i in range(l, r + 1):

# If gcd is greater than one
# check for both sides
if (math.gcd(a[i], root) > 1):
x = possibleWithState(l, i – 1, 1, a)
if (x != 1):
continue
y = possibleWithState(i + 1, r, 0, a)
if (x == 1 and y == 1) :
return 1

# If not possible
return 0

# Function that return true if it is
# possible to make Binary Search Tree
def isPossible(a, n):

# Sort the given array
a.sort()

# Check it is possible rooted at i
for i in range(n):

# Check at both sides
if (possibleWithState(0, i – 1, 1, a) and
possibleWithState(i + 1, n – 1, 0, a)):
return True

return False

# Driver Code
if __name__ == ‘__main__’:
a = [3, 6, 9, 18, 36, 108]
n = len(a)
if (isPossible(a, n)):
print(“Yes”)
else:
print(“No”)

# This code is contributed by
# Shubham Singh(SHUBHAMSINGH10)

## C#

 `// C# implementation of the appraoch  ` `using` `System;  ` ` `  `class` `GFG  ` `{  ` `     `  `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);  ` `}  ` ` `  `// Maxium number of vertices  ` `static` `int` `N = 705;  ` ` `  `// To store is it possible at  ` `// particular pace or not  ` `static` `int` `[,,]dp = ``new` `int``[N, N, 2];  ` ` `  `// Return 1 if from l to r, it is  ` `// possible with the given state  ` `static` `int` `possibleWithState(``int` `l, ``int` `r,  ` `                        ``int` `state, ``int` `[]a)  ` `{  ` `    ``// Base condition  ` `    ``if` `(l > r)  ` `        ``return` `1;  ` ` `  `    ``// If it is already calculated  ` `    ``if` `(dp[l, r, state] != -1)  ` `        ``return` `dp[l, r, state];  ` ` `  `    ``// Choose the root  ` `    ``int` `root;  ` `    ``if` `(state == 1)  ` `        ``root = a[r + 1];  ` `    ``else` `        ``root = a[l - 1];  ` ` `  `    ``// Traverse in range l to r  ` `    ``for` `(``int` `i = l; i <= r; i++)  ` `    ``{  ` ` `  `        ``// If gcd is greater than one  ` `        ``// check for both sides  ` `        ``if` `(__gcd(a[i], root) > 1)  ` `        ``{  ` `            ``int` `x = possibleWithState(l, i - 1, 1, a);  ` `            ``if` `(x != 1)  ` `                ``continue``;  ` `                 `  `            ``int` `y = possibleWithState(i + 1, r, 0, a);  ` `             `  `            ``if` `(x == 1 && y == 1)  ` `                ``return` `dp[l,r,state] = 1;  ` `        ``}  ` `    ``}  ` ` `  `    ``// If not possible  ` `    ``return` `dp[l,r,state] = 0;  ` `}  ` ` `  `// Function that return true  ` `// if it is possible to make  ` `// Binary Search Tree  ` `static` `bool` `isPossible(``int` `[]a, ``int` `n)  ` `{  ` `    ``for``(``int` `i = 0; i < dp.GetLength(0); i++)  ` `        ``for``(``int` `j = 0; j < dp.GetLength(1); j++)  ` `            ``for``(``int` `k = 0; k < dp.GetLength(2); k++)  ` `                ``dp[i, j, k]=-1;  ` ` `  `    ``// Sort the given array  ` `    ``Array.Sort(a);  ` ` `  `    ``// Check it is possible rooted at i  ` `    ``for` `(``int` `i = 0; i < n; i++)  ` ` `  `        ``// Check at both sides  ` `        ``if` `(possibleWithState(0, i - 1, 1, a) != 0 &&  ` `            ``possibleWithState(i + 1, n - 1, 0, a) != 0)  ` `        ``{  ` `            ``return` `true``;  ` `        ``}  ` ` `  `    ``return` `false``;  ` `}  ` ` `  `// Driver code  ` `public` `static` `void` `Main(String []args)  ` `{  ` `    ``int` `[]a = { 3, 6, 9, 18, 36, 108 };  ` `    ``int` `n = a.Length;  ` ` `  `    ``if` `(isPossible(a, n))  ` `        ``Console.WriteLine(``"Yes"``);  ` `    ``else` `        ``Console.WriteLine(``"No"``);  ` ` `  `}  ` `}  ` ` `  `// This code is contributed by 29AjayKumar `

Output:

```Yes
```

My Personal Notes arrow_drop_up

Be the First to upvote.

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.