**This is the program**

def **multiply_optimized**(poly1,poly2):

if not poly1 and not poly2:

return []

if poly1 == []:

return poly2

if poly2 == []:

return poly1

if len(poly1) == 1:

if poly1[0] == 0:

return [0]

else:

return [poly1[0]* x for x in poly2]

elif len(poly2) == 1:

if poly2[0] == 0:

return [0]

else:

return [poly2[0]* y for y in poly1]

(A0,A1),(B0,B1) = split(poly1,poly2)

Y = multiply_optimized(add(A0,A1),add(B0,B1))

U = multiply_optimized(A0,B0)

Z = multiply_optimized(A1,B1)

temp_ = add(U,Z)

temp = subtract(Y, temp_)

mid = max(len(poly1), len(poly2))

n = mid//2

**return** **add(add(U,increase_exponent(temp, n)),increase_exponent(Z, 2*n))**

**This is addition: -**

def add(poly1, poly2):

result = [0] * max(len(poly1), len(poly2))

for i in range(len(result)):

if i < len(poly1):

result[i] += poly1[i]

if i < len(poly2):

result[i] += poly2[i]

return result

**This is subtraction:-**

def subtract(poly1,poly2):

result = [0] * max(len(poly1), len(poly2))

for i in range(len(result)):

if i < len(poly2):

result[i] = poly2[i] - result[i]

if i < len(poly1):

result[i] = poly1[i] - result[i]

return result