Buggy python submission (verdict: Time Limit Exceeded):
N, K = map(int, input().split())
A = list(map(int, input().split()))
F = list(map(int, input().split()))
if K >= sum(A):
  print(0)
  exit()
A.sort(reverse=True)
F.sort()

#print('A:', A)
#print('F:', F)


res = K

lot = [A[k]*F[k] for k in range(N)]
#print(lot)
#print(res)

now = []
for k in range(N):
  now.append((-lot[k], k))
from heapq import heapify, heappop, heappush
from math import ceil
heapify(now)
#print(now)
f = heappop(now)
while res>0:
  #print(res)
  #print(now)
  s = heappop(now)
  big = lot[f[1]]
  small = lot[s[1]]
  cnt = ceil((big-small)/F[f[1]])
  if big == small:
    cnt = 1
  if cnt > A[f[1]]:
    print(lot[f[1]] - A[f[1]]*F[f[1]])
    exit()
  if cnt >= res:
    lot[f[1]] -= res*F[f[1]]
    break
  else:
    lot[f[1]] -= cnt*F[f[1]]
    A[f[1]] -= cnt
    res -= cnt
    heappush(now, (-lot[f[1]], f[1]))
  f = s
  
print(max(lot))

Fixed submission:
from math import ceil
N, K = map(int, input().split())
A = list(map(int, input().split()))
F = list(map(int, input().split()))
if K >= sum(A):
  print(0)
  exit()
A.sort(reverse=True)
F.sort()
lot = []
for k in range(N):
  lot.append((A[k]*F[k], k))
lot.sort(key =  lambda x:x[0],reverse=True)
high = lot[0][0]
#print('A:', A)
#print('F:', F)
#rint(lot)
def binary_search(high):
  low = 0
  mid = (low + high) //2
  while low < high:
    final = False
    mid = (low + high) //2
    #print(low, high, mid)
    if low == high-1:
      final = True
    #print(low, high, mid)
    res = K
    flag = True
    for k in range(N):
      if res < 0:
        break
      else:
        if lot[k][0] <= mid:
          break
        else:
          res -= ceil((lot[k][0]-mid)/F[lot[k][1]])
          continue
    if res < 0:
      flag = False
    #print(flag)
    if flag:
      high = mid
    else:
      if final:
        mid += 1
      low = mid
    #print(low, high, mid)
  #return None
  return mid

print(binary_search(high))

Buggy python submission (verdict: Time Limit Exceeded):
N, K = map(int, input().split())
A = list(map(int, input().split()))
F = list(map(int, input().split()))
if K >= sum(A):
  print(0)
  exit()
A.sort(reverse=True)
F.sort()
from math import gcd
def lcm(x, y):
  return (x*y)//gcd(x, y)

f_lcm = 1
for k in range(N):
  f_lcm = lcm(f_lcm, F[k])

portion = [f_lcm//F[k] for k in range(N)]


#print('A:', A)
#print('F:', F)
#print('portion:', portion)
lot = [0 for _ in range(N)]


sa = sum(A) - K
sp = sum(portion)
for k in range(N):
  point = sa*portion[k]//sp
  if point > A[k]:
    lot[k] += A[k]*F[k]
    A[k] = 0
  else:
    lot[k] += point *F[k]
    A[k] -= point
res = sum(A) - K
#print(lot)
#print(A)
#print(res)

foo = []
for k in range(N):
  if A[k] == 0:
    continue
  else:
    foo.append((lot[k]+F[k], A[k], k))

from heapq import heapify, heappop, heappush
heapify(foo)
while res>0:
  res -= 1
  item = heappop(foo)
  lot[item[2]] = item[0]
  if item[1] == 1:
    continue
  else:
    heappush(foo, (item[0]+F[item[2]], item[1]-1, item[2]))
  #print(foo)
print(max(lot))

Fixed submission:
from math import ceil
N, K = map(int, input().split())
A = list(map(int, input().split()))
F = list(map(int, input().split()))
if K >= sum(A):
  print(0)
  exit()
A.sort(reverse=True)
F.sort()
lot = []
for k in range(N):
  lot.append((A[k]*F[k], k))
lot.sort(key =  lambda x:x[0],reverse=True)
high = lot[0][0]
#print('A:', A)
#print('F:', F)
#rint(lot)
def binary_search(high):
  low = 0
  mid = (low + high) //2
  while low < high:
    final = False
    mid = (low + high) //2
    #print(low, high, mid)
    if low == high-1:
      final = True
    #print(low, high, mid)
    res = K
    flag = True
    for k in range(N):
      if res < 0:
        break
      else:
        if lot[k][0] <= mid:
          break
        else:
          res -= ceil((lot[k][0]-mid)/F[lot[k][1]])
          continue
    if res < 0:
      flag = False
    #print(flag)
    if flag:
      high = mid
    else:
      if final:
        mid += 1
      low = mid
    #print(low, high, mid)
  #return None
  return mid

print(binary_search(high))

Buggy python submission (verdict: Time Limit Exceeded):
N, K = map(int, input().split())
A = list(map(int, input().split()))
F = list(map(int, input().split()))
if K >= sum(A):
  print(0)
  exit()
A.sort(reverse=True)
F.sort()
from math import gcd
def lcm(x, y):
  return (x*y)//gcd(x, y)

f_lcm = 1
for k in range(N):
  f_lcm = lcm(f_lcm, F[k])

portion = [f_lcm//F[k] for k in range(N)]
sp = sum(portion)

#print('A:', A)
#print('F:', F)
#print('portion:', portion)
lot = [0 for _ in range(N)]


sa = sum(A) - K
for k in range(N):
  point = sa*portion[k]//sp
  if A[k] == 0:
    continue
  elif point > A[k]:
    lot[k] += A[k]*F[k]
    A[k] = 0
  else:
    lot[k] += point *F[k]
    A[k] -= point
res = sum(A) - K
#print(lot)
#print(A)
#print(res)

while res>0:
  second  = float('inf')
  for k in range(N):
    if A[k] > 0:
      second = min(second, lot[k] + F[k])
  for k in range(N):
    if A[k] > 0:
      if second == lot[k] + F[k]:
        lot[k] += F[k]
        A[k] -= 1
        res -= 1
  if res <0:
    break
  sa = sum(A) - K
  for k in range(N):
    point = sa*portion[k]//sp
    if A[k] == 0:
      continue
    elif point > A[k]:
      lot[k] += A[k]*F[k]
      A[k] = 0
    else:
      lot[k] += point *F[k]
      A[k] -= point
  res = sum(A) - K

print(max(lot))

Fixed submission:
from math import ceil
N, K = map(int, input().split())
A = list(map(int, input().split()))
F = list(map(int, input().split()))
if K >= sum(A):
  print(0)
  exit()
A.sort(reverse=True)
F.sort()
lot = []
for k in range(N):
  lot.append((A[k]*F[k], k))
lot.sort(key =  lambda x:x[0],reverse=True)
high = lot[0][0]
#print('A:', A)
#print('F:', F)
#rint(lot)
def binary_search(high):
  low = 0
  mid = (low + high) //2
  while low < high:
    final = False
    mid = (low + high) //2
    #print(low, high, mid)
    if low == high-1:
      final = True
    #print(low, high, mid)
    res = K
    flag = True
    for k in range(N):
      if res < 0:
        break
      else:
        if lot[k][0] <= mid:
          break
        else:
          res -= ceil((lot[k][0]-mid)/F[lot[k][1]])
          continue
    if res < 0:
      flag = False
    #print(flag)
    if flag:
      high = mid
    else:
      if final:
        mid += 1
      low = mid
    #print(low, high, mid)
  #return None
  return mid

print(binary_search(high))

Buggy python submission (verdict: Time Limit Exceeded):
N, K = map(int, input().split())
A = list(map(int, input().split()))
F = list(map(int, input().split()))
if K >= sum(A):
  print(0)
  exit()
A.sort(reverse=True)
F.sort()
from math import gcd
def lcm(x, y):
  return (x*y)//gcd(x, y)

f_lcm = 1
for k in range(N):
  f_lcm = lcm(f_lcm, F[k])

portion = [f_lcm//F[k] for k in range(N)]


#print('A:', A)
#print('F:', F)
#print('portion:', portion)
lot = [0 for _ in range(N)]


sa = sum(A) - K
sp = sum(portion)
for k in range(N):
  point = sa*portion[k]//sp
  if point > A[k]:
    lot[k] += A[k]*F[k]
    A[k] = 0
  else:
    lot[k] += point *F[k]
    A[k] -= point
res = sum(A) - K
#print(lot)
#print(A)
#print(res)

while res>0:
  second  = float('inf')
  for k in range(N):
    if A[k] > 0:
      second = min(second, lot[k] + F[k])
  for k in range(N):
    if A[k] > 0:
      if second == lot[k] + F[k]:
        lot[k] += F[k]
        A[k] -= 1
        res -= 1

print(max(lot))

Fixed submission:
from math import ceil
N, K = map(int, input().split())
A = list(map(int, input().split()))
F = list(map(int, input().split()))
if K >= sum(A):
  print(0)
  exit()
A.sort(reverse=True)
F.sort()
lot = []
for k in range(N):
  lot.append((A[k]*F[k], k))
lot.sort(key =  lambda x:x[0],reverse=True)
high = lot[0][0]
#print('A:', A)
#print('F:', F)
#rint(lot)
def binary_search(high):
  low = 0
  mid = (low + high) //2
  while low < high:
    final = False
    mid = (low + high) //2
    #print(low, high, mid)
    if low == high-1:
      final = True
    #print(low, high, mid)
    res = K
    flag = True
    for k in range(N):
      if res < 0:
        break
      else:
        if lot[k][0] <= mid:
          break
        else:
          res -= ceil((lot[k][0]-mid)/F[lot[k][1]])
          continue
    if res < 0:
      flag = False
    #print(flag)
    if flag:
      high = mid
    else:
      if final:
        mid += 1
      low = mid
    #print(low, high, mid)
  #return None
  return mid

print(binary_search(high))