# Find longest bitonic sequence such that increasing and decreasing parts are from two different arrays in Python

Suppose we have two arrays; we have to find the longest possible bitonic sequence so that the increasing part should be from first array and should be a subsequence of first array. similarly decreasing part of must be from second array and a subsequence of the second one.

So, if the input is like A = [2, 6, 3, 5, 4, 6], B = [9, 7, 5, 8, 4, 3], then the output will be [2, 3, 4, 6, 9, 7, 5, 4, 3]

To solve this, we will follow these steps −

• Define a function index_ceiling() . This will take arr, T, left, right, key

• while right - left > 1, do

• mid := left +(right - left) / 2;

• if arr[T[mid]] >= key, then

• right := mid

• otherwise,

• left := mid

• return right

• Define a function long_inc_seq() . This will take A

• n := size of A

• tails_idx := an array of size n, fill with 0

• prev_idx := an array of size n, fill with -1

• length := 1

• for i in range 1 to n, do

• if A[i] < A[tails_idx], then

• tails_idx := i

• otherwise when A[i] > A[tails_idx[length - 1]], then

• prev_idx[i] := tails_idx[length - 1]

• tails_idx[length] := i

• length := length + 1

• otherwise,

• pos := index_ceiling(A, tails_idx, -1, length - 1, A[i])

• prev_idx[i] := tails_idx[pos - 1]

• tails_idx[pos] := i

• i := tails_idx[length - 1]

• while i >= 0, do

• insert A[i] at the end of answer

• i := prev_idx[i]

• From the main method, do the following −

• n1 := size of A, n2 := size of B

• long_inc_seq(A)

• B := reverse B

• long_inc_seq(B)

## Example

Let us see the following implementation to get better understanding −

answer = []
def index_ceiling(arr,T, left,right, key):
while (right - left > 1):
mid = left + (right - left) // 2;
if (arr[T[mid]] >= key):
right = mid
else:
left = mid
return right
def long_inc_seq(A):
n = len(A)
tails_idx = *(n)
prev_idx = [-1]*(n)
length = 1
for i in range(1, n):
if (A[i] < A[tails_idx]):
tails_idx = i
elif (A[i] > A[tails_idx[length - 1]]):
prev_idx[i] = tails_idx[length - 1]
tails_idx[length] = i
length += 1
else:
pos = index_ceiling(A, tails_idx, -1, length - 1, A[i])
prev_idx[i] = tails_idx[pos - 1]
tails_idx[pos] = i
i = tails_idx[length - 1]
while(i >= 0):
i = prev_idx[i]
def long_bitonic(A,B):
n1 = len(A)
n2 = len(B)
long_inc_seq(A)
B = B[::-1]
long_inc_seq(B)
A = [2, 6, 3, 5, 4, 6]
B = [9, 7, 5, 8, 4, 3]
long_bitonic(A,B)
print(answer)

## Input

[2, 6, 3, 5, 4, 6], [9, 7, 5, 8, 4, 3]

## Output

[2, 3, 4, 6, 9, 7, 5, 4, 3]