Problem:
 Score: 500 points    Problem Statement  Takahashi will take part in an eating contest. Teams of N members will compete in this contest, and Takahashi's team consists of N players numbered 1 through N from youngest to oldest. The consumption coefficient of Member i is A_i .  In the contest, N foods numbered 1 through N will be presented, and the difficulty of Food i is F_i . The details of the contest are as follows:   A team should assign one member to each food, and should not assign the same member to multiple foods.  It will take x \times y seconds for a member to finish the food, where x is the consumption coefficient of the member and y is the difficulty of the dish.  The score of a team is the longest time it takes for an individual member to finish the food.   Before the contest, Takahashi's team decided to do some training. In one set of training, a member can reduce his/her consumption coefficient by 1 , as long as it does not go below 0 . However, for financial reasons, the N members can do at most K sets of training in total.  What is the minimum possible score of the team, achieved by choosing the amounts of members' training and allocating the dishes optimally?      Constraints   All values in input are integers.  1 \leq N \leq 2 \times 10^5  0 \leq K \leq 10^{18}  1 \leq A_i \leq 10^6\ (1 \leq i \leq N)  1 \leq F_i \leq 10^6\ (1 \leq i \leq N)         Input  Input is given from Standard Input in the following format:  N  K  A_1  A_2  ...  A_N  F_1  F_2  ...  F_N       Output  Print the minimum possible score of the team.        Sample Input 1 3 5
4 2 1
2 3 1      Sample Output 1 2  They can achieve the score of 2 , as follows:   Member 1 does 4 sets of training and eats Food 2 in (4-4) \times 3 = 0 seconds.  Member 2 does 1 set of training and eats Food 3 in (2-1) \times 1 = 1 second.  Member 3 does 0 sets of training and eats Food 1 in (1-0) \times 2 = 2 seconds.   They cannot achieve a score of less than 2 , so the answer is 2 .       Sample Input 2 3 8
4 2 1
2 3 1      Sample Output 2 0  They can choose not to do exactly K sets of training.       Sample Input 3 11 14
3 1 4 1 5 9 2 6 5 3 5
8 9 7 9 3 2 3 8 4 6 2      Sample Output 3 12

Solution (Python):
n, k = list(map(int, input().split()))
a = list(map(int, input().split()))
f = list(map(int, input().split()))

a.sort(reverse=True)
f.sort(reverse=False)

def isok(mid):
    total = 0
    for i in range(n):
        if a[i] * f[i] <= mid:
            continue
        total += a[i] - mid // f[i]
    return total <= k

ng = -1
ok = a[0] * f[-1] + 1
while abs(ok - ng) > 1:
    mid = (ok + ng) // 2
    if isok(mid):
        ok = mid
    else:
        ng = mid

print(ok)

Solution (Python):
def check(limit, max_training, costs, volumes):
    from math import floor
    remain_training = max_training
    for id, (cost, volume) in enumerate(zip(costs, volumes)):
        if cost * volume <= limit:
            continue
        else:
            lowest_cost = floor(limit / volume)
            remain_training -= (cost - lowest_cost)
        if remain_training < 0:
            return False
    return True


def main():
    n, k = map(int, input().rstrip("\n").split(" "))
    costs = list(map(int, input().rstrip("\n").split(" ")))
    volumes = list(map(int, input().rstrip("\n").split(" ")))

    costs.sort()
    volumes.sort(reverse=True)
    queue = []
    total_cost = 0

    success = False

    max_cost = max([cost * volume for cost, volume in zip(costs, volumes)])
    min_cost = 0

    while (min_cost + 1) < max_cost:
        center_cost = (min_cost + max_cost) // 2
        success = check(center_cost, k, costs, volumes)
        if success:
            max_cost = center_cost
        else:
            min_cost = center_cost
    if check(min_cost, k, costs, volumes):
        print(min_cost)
    else:
        print(max_cost)


if __name__ == '__main__':
    main()

Solution (Python):
import sys
read=sys.stdin.buffer.read
readline=sys.stdin.buffer.readline
readlines=sys.stdin.buffer.readlines

N,K=map(int,readline().split())
A=list(map(int,readline().split()))
F=list(map(int,readline().split()))




A.sort()
F.sort(reverse=True)



left=-1
right=N*A[-1]*F[0]


while left+1<right:
  mid=(left+right)//2
  tmp=0
  for i in range(N):
    tmp+=max(A[i]-mid//F[i],0)
    
  if tmp<=K:
    right=mid
  else:
    left=mid
  

print(right)

Solution (Python):
import sys
read=sys.stdin.buffer.read
readline=sys.stdin.buffer.readline
readlines=sys.stdin.buffer.readlines

N,K=map(int,input().split())
A=list(map(int,input().split()))
F=list(map(int,input().split()))




A.sort()
F.sort(reverse=True)



left=-1
right=2*10**17


while left+1<right:
  mid=(left+right)//2
  tmp=0
  for i in range(N):
    tmp+=max(A[i]-mid//F[i],0)
    
  if tmp<=K:
    right=mid
  else:
    left=mid
  

print(right)

Solution (Python):
import sys
read=sys.stdin.buffer.read
readline=sys.stdin.buffer.readline
readlines=sys.stdin.buffer.readlines

N,K=map(int,input().split())
A=list(map(int,input().split()))
F=list(map(int,input().split()))




A.sort()
F.sort(reverse=True)



left=-1
right=10**18


while left+1<right:
  mid=(left+right)//2
  tmp=0
  for i in range(N):
    tmp+=max(A[i]-mid//F[i],0)
    
  if tmp<=K:
    right=mid
  else:
    left=mid
  

print(right)

Solution (Python):
import sys
read=sys.stdin.buffer.read
readline=sys.stdin.buffer.readline
readlines=sys.stdin.buffer.readlines

N,K=map(int,readline().split())
A=list(map(int,readline().split()))
F=list(map(int,readline().split()))




A.sort()
F.sort(reverse=True)



left=-1
right=10**18


while left+1<right:
  mid=(left+right)//2
  tmp=0
  for i in range(N):
    tmp+=max(A[i]-mid//F[i],0)
    
  if tmp<=K:
    right=mid
  else:
    left=mid
  

print(right)

Solution (Python):
import sys
read=sys.stdin.buffer.read
readline=sys.stdin.buffer.readline
readlines=sys.stdin.buffer.readlines

N,K=map(int,readline().split())
A=list(map(int,readline().split()))
F=list(map(int,readline().split()))




A.sort()
F.sort(reverse=True)



left=-1
right=10**18


while left+1<right:
  mid=(left+right)//2
  tmp=[0]*(N)
  for i in range(N):
    tmp[i]=max(A[i]-mid//F[i],0)
    
  if sum(tmp)<=K:
    right=mid
  else:
    left=mid
  

print(right)

Solution (Python):









 

 
n, k = map(int, input().split())
a = []
a = list(map(int, input().split()))
f = []
f = list(map(int, input().split()))
 
a.sort()
f.sort(reverse=True)
ans = 0
 
maxaf = 0
for i in range(n):
    maxaf = max(maxaf, a[i] * f[i])
 
left = 0
right = maxaf
 
while left < right:
    
    mid = (left + right) // 2
    ktemp = k
    renewleft = False
    for i in range(n):
        if a[i] * f[i] > mid:
            if (a[i] * f[i] - mid + f[i] - 1) // f[i] > ktemp:
                left = mid + 1
                renewleft = True
                break
            else:
                ktemp -= (a[i] * f[i] - mid + f[i] - 1) // f[i]
    if not renewleft:
        right = mid
 
print(left)

Solution (Python):
n,k=map(int,input().split())
a=list(map(int,input().split()))
f=list(map(int,input().split()))

a.sort()
f.sort(reverse=True)

pi=[a[i]*f[i] for i in range(n)]

l=-1
r=max(pi)

while l+1<r:
  x=(l+r)//2
  s=sum([max(a[i]-x//f[i],0) for i in range(n)])
  if s<=k:
    r=x
  else:
    l=x
print(r)

Solution (Python):
N, K = map(int, input().split())
a = [int(c) for c in input().split()]
f = [int(c) for c in input().split()]
a.sort()
f.sort(reverse=True)
def check(n):
  m = K
  for i in range(N):
    m -= max(0, a[i]-n//f[i])
    if m<0:
      return False
  return True
r = 0
l = a[-1]*f[0]
X = (l-r)//2+r
while not (check(X)^check(X+1)) :
  if check(X):
    l = l - (l-r)//2
  else:
    r = (l-r)//2 + r
  X = (l-r)//2+r
  if check(0):
    print(0)
    break
else:
  print(X+1)

Solution (Python):
import time
st_time=time.time()

from heapq import heappush, heappop
from collections import deque,defaultdict,Counter
import itertools
from itertools import permutations,combinations
import sys
import bisect
import string
import math
import random
def I():
    return int(input())
def MI():
    return map(int,input().split())
def LI():
    return [int(i) for i in input().split()]
def LI_():
    return [int(i)-1 for i in input().split()]
def show(*inp,end='\n'):
    if show_flg:
        print(*inp,end=end)
YN=['Yes','No']
mo=10**9+7
inf=float('inf')
ts=time.time()
sys.setrecursionlimit(10**6)
input=sys.stdin.readline
show_flg=False


ans=0
n,k=LI()
a=LI()
f=LI()

a=sorted(a)[::-1]
f=sorted(f)
p=[a[i]*f[i] for i in range(n)]
show(a)
show(f)
show(p)

def check(z):
    c=0
    for i in range(n):
        c+=max(0,a[i]-z//f[i])
    if c<=k:
        rt=True
    else:
        rt=False
    return rt

ng=-1
ok=10**12

while ok-ng>1:
    mid=(ok+ng)//2
    fl=check(mid)
    if fl:
        ok=mid
    else:
        ng=mid
    show(ok,ng,fl)

ans=ok
print(ans)

Solution (Python):
NK = input().split(' ')
N = int(NK[0])
K = int(NK[1])
An = sorted(list(map(int,input().split(' '))))
Fn = sorted(list(map(int,input().split(' '))),reverse=True)
An_s = sum(An)

min_time = -1 
max_time = An[N-1] * Fn[0] 
x_cadidate = An[N-1] * Fn[0] 
middle_time = -1
range_n = range(N)

while True:
    
    middle_time = (min_time + max_time)//2 
    
    sum_ax = 0
    for i in range_n:
        ax = middle_time//Fn[i] 
        if ax < An[i]:
            sum_ax += ax
        else:
            sum_ax += An[i]
    if  min_time+1 == max_time: 
        break
    elif An_s - sum_ax <= K:
        if x_cadidate > middle_time:
            x_cadidate = middle_time 
        max_time = middle_time   
    else:
        min_time = middle_time   

print(x_cadidate)

Solution (Python):
N, K = list(map(int, input().split()))
A = sorted(list(map(int, input().split())))
F = sorted(list(map(int, input().split())))[::-1]


M = max([a*f for a, f in zip(A, F)])



def is_possible(x):
    return sum([max(0, a-x//f) for a, f in zip(A, F)]) <= K


left = -1
right = M
while left + 1 < right:
    mid = (left + right)//2
    if is_possible(mid):
        right = mid
    else:
        left = mid

print(right)

Solution (Python):
N, K = list(map(int, input().split()))
A = sorted(list(map(int, input().split())))
F = sorted(list(map(int, input().split())))[::-1]
B = sum(A)

M = max([a*f for a, f in zip(A, F)])

def is_possible(x):
    return B - sum([min(a, x//f) for a, f in zip(A, F)]) <= K


left = -1
right = M
while left + 1 < right:
    mid = (left + right)//2
    if is_possible(mid):
        right = mid
    else:
        left = mid

print(right)

Solution (Python):
import sys
input = sys.stdin.readline


N, K = map(int, input().split())
A = list(map(int, input().split()))
F = list(map(int, input().split()))


import numpy as np
A = np.array(A)
F = np.array(F)

A = np.sort(A)[::-1]
F = np.sort(F)
B = np.sum(A)
M = max([a*f for a, f in zip(A, F)])

def is_possible(x):
    return B - np.minimum(A, x//F).sum() <= K

left = -1
right = M
while left + 1 < right:
    mid = (left + right)//2
    if is_possible(mid):
        right = mid
    else:
        left = mid

print(right)

Solution (Python):
import sys
input = sys.stdin.readline

N, K = map(int,input().split())
A = sorted((map(int,input().split())), reverse=True)
F = sorted(map(int,input().split()))

def judge(k):
    cnt = 0
    for a, f in zip(A, F):
        x = k//f
        d = a - x if a > x else 0
        cnt += d
    if cnt <= K:
        return True
    else:
        return False

def biserch(ok,ng,judge):
    while abs(ok-ng) > 1:
        mid = (ok+ng) // 2
        if judge(mid):
            ok = mid
        else:
            ng = mid
    return ok

ans = biserch(10**12, -1, judge)
print(ans)

Solution (Python):

import numpy as np


def solve(*args: str) -> str:
    n, k = map(int, args[0].split())
    A = np.array(sorted(list(map(int, args[1].split()))))
    F = np.array(sorted(list(map(int, args[2].split())), reverse=True))

    right = 1+A[-1]*F[0]
    left = -1

    total = A.sum()
    while left+1 < right:
        mid = (left+right)//2
        if total - np.minimum(A, mid//F).sum() <= k:
            right = mid
        else:
            left = mid

    return str(right)


if __name__ == "__main__":
    print(solve(*(open(0).read().split('\n'))))

Solution (Python):
import sys
import math
import bisect
from collections import defaultdict, deque
from heapq import heappush, heappop


def LI(): return [int(x) for x in sys.stdin.readline().split()]


def I(): return int(sys.stdin.readline())


def S():
    res = list(sys.stdin.readline())
    if res[-1] == "\n":
        return res[:-1]
    return res


def IR(n):
    return [I() for i in range(n)]



def A():
    return



def B():
    return



def C():
    n = I()
    for i in range(int(n ** 0.5), 0, -1):
        if n % i == 0:
            print(i + n // i - 2)
            return
    return



def D():
    a, b, x = LI()
    if (x <= a * a * b / 2):
        print(math.degrees(math.atan(a * b * b / x / 2)))
    else:
        print(math.degrees(math.atan(2 * (a * a * b - x) / a ** 3)))
    return



def E():
    n, k = LI()
    a = LI()
    f = LI()
    a.sort()
    f.sort(reverse=True)
    left = 0
    right = 0
    for a_i, f_i in zip(a, f):
        right = max(a_i * f_i, right)
    while (left != right):
        mid = (left + right) >> 1
        score = 0
        for i in range(n):
            if a[i] * f[i] > mid:
                score += a[i] - mid // f[i]
        if score <= k:
            right = mid
        else:
            left = mid + 1
    print(left)
    return



def F():
    return



def resolve():
    E()
    return



if __name__ == "__main__":
    E()

Solution (Python):
import math

N, K = [int(x) for x in input().split()]
A = [int(x) for x in input().split()]
F = [int(x) for x in input().split()]


A.sort(reverse=True)
F.sort()
max_af = 0
for ind,a in enumerate(A):
    max_af = max(a*F[ind], max_af)

if(sum(A)<=K):
    print(0)
else:
    lower = -1
    higher = 10**12+1

    while(higher-lower>1):
        x = (lower + higher)//2
        
        k = K
        for ind,a in enumerate(A):
            mu = a*F[ind]
            if(mu<=x):
                continue
            else:
                k -= math.ceil((mu-x)/F[ind])
        if(k>=0):
            higher = x
        else:
            lower = x

    print(higher)

Solution (Python):
N,K = map(int,input().split())
A = list(map(int,input().split()))
F = list(map(int,input().split()))

A.sort()
F.sort(reverse=True)

sumA = sum(A)
if  K >= sumA:
    print(0)
    exit()

def isok(x):
    k = 0
    for a, f in zip(A, F):
        if a > x//f:
            k += a - (x//f)
            if k > K:
                return False
    return True

ng = -1
ok = 10**12+1

while ok - ng > 1:
    mid = (ok + ng)//2
    if isok(mid):
        ok = mid
    else:
        ng = mid
print(ok)

Solution (Python):
n,k=map(int,input().split())

a=list(map(int,input().split()))
f=list(map(int,input().split()))
cnt=[0]*n
a.sort()
f.sort(reverse=True)
for i in range(n):
    cnt[i]=a[i]*f[i]
def judge(s):
    tmp=k
    for i in range(n):
        if cnt[i]>s:
            if (cnt[i]-s)%f[i]==0:
                vv=(cnt[i]-s)//f[i]
            else:
                vv=1+(cnt[i]-s)//f[i]
            tmp-=vv
    if tmp<0:
        return False
    return True

left=-1
right=10**18

while left+1<right:
    mid=(left+right)//2
    if judge(mid):
        right=mid
    else:
        left=mid

print(right)

Solution (Python):
import numpy as np

import sys
input = sys.stdin.buffer.readline

n, k = map(int, input().split())
a = np.array(input().split(), np.int64)
f = np.array(input().split(), np.int64)

a.sort()
f.sort()

f_ = f[::-1]

left = -1
right = (a*f).sum()
while left + 1 < right:
  mid = (left + right) // 2
  r = np.maximum(0, a - mid//f_).sum() <= k
  if r:
    right = mid
  else:
    left = mid
print(right)

Solution (Python):
N,K = map(int,input().split())
A = list(map(int,input().split()))
F = list(map(int,input().split()))
A.sort()
F.sort(reverse=True)

L = -1
R = 10**12 +1 
while R-L>1:
    Mid = (L+R)//2
    tmp = 0
    for a,f in zip(A,F):
        tmp += max(0, a-Mid//f)
    if tmp<=K:
        R = Mid
    else:
        L = Mid
print(R)

Solution (Python):
from math import ceil
N,K = map(int,input().split())
A = list(map(int,input().split()))
F = list(map(int,input().split()))
A.sort()
F.sort(reverse=True)
def check(m):
    used = 0
    for i in range(N):
        b = ceil(A[i]-m/F[i])
        if b < 0:
            b = 0
        if A[i]-b < 0:
            return False
        used += b
        if used > K:
            return False 
    return True
left = -1
right = A[-1]*F[0]
while right-left > 1:
    mid = (right+left)//2
    if check(mid):
        right = mid
    else:
        left = mid
print(right)

Solution (Python):
import numpy as np
 
a,b=map(int,input().split())
A=np.array(sorted(list(map(int,input().split()))))
F=np.array(sorted(list(map(int,input().split())),reverse=True))
 
s=A.sum()
 
x=-1
y=10**12
while x+1<y:
  mid=(x+y)//2
  if s-np.minimum(A,mid//F).sum()<=b:
    y=mid
  else:
    x=mid
print(y)

Solution (Python):

N, K = map(int, input().split())
A = list(map(int, input().split()))
F = list(map(int, input().split()))








A = sorted(A)
F = sorted(F, reverse=True)


ng = -1
ok = 10 ** 12  

while ok - ng > 1:  
    mid = (ok + ng) // 2
    cost = 0

    for i, e in enumerate(A):
        cost += max(0, e - mid // F[i])
    
    if cost <= K:
        ok = mid
    
    else:
        ng = mid

print(ok)

Solution (Python):
N, K = map(int, input().split())
A = list(map(int, input().split()))
F = list(map(int, input().split()))

A.sort()
F.sort(reverse=True)


def shugyou_count(X):
    
    count = 0
    for a, f in zip(A, F):
        count += max(0, a - X // f)
    return count



l = -1
r = max(A) * max(F)
while l + 1 < r:
    X = (l + r) // 2
    if shugyou_count(X) <= K:
        r = X
    else:
        l = X
print(r)

Solution (Python):

import numpy as np


def is_ok(mid, K, A, F):
    return np.maximum(A - mid // F, 0).sum() <= K


def main():
    N, K = input_line(int, int)
    A = input_line([int])
    F = input_line([int])
    A = np.array(sorted(A))
    F = np.array(sorted(F, reverse=True))

    ng = -1
    ok = int(1e12)
    while ok - ng > 1:
        mid = (ng + ok) // 2
        if is_ok(mid, K, A, F):
            ok = mid
        else:
            ng = mid
    print(ok)


def input_line(*types):
    if isinstance(types[0], list):
        return [types[0][0](x) for x in input().split()]
    elif len(types) == 1:
        return types[0](input())
    else:
        return [t(x) for t, x in zip(types, input().split())]


if __name__ == "__main__":
    main()

Solution (Python):
import sys

input = sys.stdin.readline


class AtCoder:
    def main(self):
        N, K = map(int, input().split())
        A = list(map(int, input().split()))
        F = list(map(int, input().split()))

        A.sort()
        F.sort(reverse=True)

        l, r = -1, 10 ** 12
        while l + 1 < r:
            mid = (l + r) // 2

            s = 0
            for i in range(N):
                s += max(0, A[i] - mid // F[i])
            if s <= K:
                r = mid
            else:
                l = mid
        print(r)



if __name__ == '__main__':
    AtCoder().main()

Solution (Python):
import numpy as np

N, K = map(int, input().split())
A = np.array(input().split(), np.int64)
F = np.array(input().split(), np.int64)
A.sort()
F.sort()
F = F[::-1]

l = 0
r = (A * F).max()

while l < r:
    m = (l + r) // 2
    if np.maximum(A - m // F, 0).sum() <= K:
        r = m
    else:
        l = m + 1

print(r)

Solution (Python):
import numpy as np

N, K = map(int, input().split())
A = np.sort(list(map(int, input().split())))
F = np.sort(list(map(int, input().split())))[::-1]

l, r = 0, 10**12
m = (l + r) // 2

while True:
  if np.maximum(A - m//F, 0).sum() <= K:
    r = m
  else:
    l = m
  
  m = (l + r) // 2
  if r == l + 1:
    if np.maximum(A - l//F, 0).sum() <= K:
      x = l
    else:
      x = r
    break

print(x)

Solution (Python):
import numpy as np
n,k=map(int,input().split())
a=[int(i) for i in input().split()]
f=[int(i) for i  in input().split()]
A=np.array(sorted(a))
F=np.array(sorted(f, reverse=True))
left=-1
right=10**12
while left+1<right:
    x=(left+right)//2
    if np.maximum(A-x//F , 0).sum()<=k:
        right=x
    else:
        left=x
print(right)

Solution (Python):
import numpy as np
n,k=map(int,input().split())
a=[int(i) for i in input().split()]
f=[int(i) for i  in input().split()]

A=np.array(sorted(a))
F=np.array(sorted(f, reverse=True))


left=-1
right=10**12
s=A.sum()


while left+1<right:
    x=(left+right)//2
    if np.maximum(A-x//F , 0).sum()<=k:
        
        right=x
    else:
        
        left=x
print(right)

Solution (Python):
n,k=map(int,input().split())
aa=list(map(int,input().split()))
bb=list(map(int,input().split()))
aa.sort()
bb.sort(reverse=True)

low=0
high=max([aa[i]*bb[i] for i in range(n)])
while low<high and abs(high-low)>=2:
    mid=(low+high)//2
    tot=0
    for i in range(n):
        a=mid//bb[i]
        ans=max(aa[i]-a,0)
        tot+=ans
    
    if tot<=k:
        high=mid
    else:
        low=mid+1

for i in range(low,high+1):
    tot=0
    for ii in range(n):
        a=i//bb[ii]
        ans=max(aa[ii]-a,0)
        tot+=ans
   
    if tot<=k:
        ans=i
        break
print(ans)

Solution (Python):
import sys
import math
n, k = map(int, sys.stdin.readline().strip().split())
a = list(map(int, sys.stdin.readline().strip().split()))
f = list(map(int, sys.stdin.readline().strip().split()))

a = sorted(a)  
f = sorted(f, reverse=True)  


def team_result(a, f):
    eat = []
    for i, j in zip(a, f):
        eat.append(i * j)
    return(max(eat))


r = team_result(a, f)
l = -1  
while(l + 1 < r):
    mid = (l + r) // 2

    train_cost = 0
    for i, j in zip(a, f):
        train_cost += max(0, math.ceil(i - mid / j))

    if train_cost <= k:
        r = mid
    else:
        l = mid

print(r)

Solution (Python):
n,k = map(int,input().split())
a = [int(x) for x in input().split()]
b = [int(x) for x in input().split()]
a.sort()
b.sort(reverse=True)


def ok(mid,a,b,k,n):
    tmp = 0
    for i in range(n):
        if a[i] * b[i] > mid:
            tmp += a[i] - mid//b[i]
    if tmp > k:
        return 1
    else:
        return -1


def bin_search(a,b,k,n):
    l = 0
    r = 10**12
    while l <= r:
        mid = l + (r - l)//2
        res = ok(mid,a,b,k,n)
        if res < 0:
            r = mid - 1
        else:
            l = mid + 1
    return l


print(bin_search(a,b,k,n))

Solution (Python):
N, K = map(int, input().split())
A = list(map(int, input().split()))
F = list(map(int, input().split()))

A.sort()
F.sort(reverse=True)
AF = [A[i] * F[i] for i in range(N)]

l = -1
r = max(AF)
while l + 1 < r:
    x = (l + r) // 2
    s = sum([max(A[i] - x//F[i], 0) for i in range(N)])
    if s <= K:
        r = x
    else:
        l = x

print(r)

Solution (Python):
import numpy as np
 
a,b=map(int,input().split())
A=np.array(sorted(list(map(int,input().split()))))
F=np.array(sorted(list(map(int,input().split())),reverse=True))
 
s=A.sum()
 
x=-1
y=10**12
while x+1<y:
  mid=(x+y)//2
  if s-np.minimum(A,mid//F).sum()<=b:
    y=mid
  else:
    x=mid
print(y)

Solution (Python):
import sys
sys.setrecursionlimit(1000000000)
ii = lambda: int(input())
ii0 = lambda: ii() - 1
mis = lambda: map(int, input().split())
lmis = lambda: list(mis())
INF = float('inf')

def main():
    N, K = mis()
    A = lmis()
    A.sort(reverse=True)
    F = lmis()
    F.sort()
    
    class solver:
        def __getitem__(self, score_limit):
            k = K
            for i in range(N):
                if A[i]*F[i] > score_limit:
                    k -= A[i] - score_limit//F[i]
                    if k < 0:
                        return False
            return True
    
    import bisect
    print(bisect.bisect_left(solver(), True, hi=A[0]*F[-1]))

main()

Solution (Python):
import heapq
import math
import os
import sys

import numpy as np

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")

sys.setrecursionlimit(2147483647)
INF = float("inf")
IINF = 10 ** 18
MOD = 10 ** 9 + 7

N, K = list(map(int, sys.stdin.readline().split()))
A = list(map(int, sys.stdin.readline().split()))
F = list(map(int, sys.stdin.readline().split()))

if N == 1:
    a = A[0]
    f = F[0]
    ans = max(a - K, 0) * f
    print(ans)
    exit()

A = np.array(A, dtype=int)
F = np.array(F, dtype=int)
A.sort()
F.sort()
F = F[::-1]


def required_k(score):
    
    return np.ceil(np.maximum(A - score / F, 0)).sum()


ok = (A * F).max()
ng = -1
while abs(ok - ng) > 1:
    score = (ok + ng) // 2
    if required_k(score) <= K:
        ok = score
    else:
        ng = score
print(ok)

Solution (Python):
import math
n,k = map(int, input().split())
alst = list(map(int, input().split()))
flst = list(map(int, input().split()))

sorted_flst = sorted(flst, key = lambda x: -x)
sorted_alst = sorted(alst)

pair_lst = []
for a, b in zip(sorted_flst, sorted_alst):
    pair_lst.append((a*b, a))
sorted_pair_lst = sorted(pair_lst, key = lambda x:-x[0])

def judge(sorted_pair_lst, x):
    cnt = 0
    for pair in sorted_pair_lst:
        if pair[0] <= x:
            return True
        else:
            cnt += math.ceil((pair[0] - x) / pair[1])
            if cnt > k:
                return False
    return True

low = 0
high = 10**15
while high - low > 1:
    middle = (low+high) // 2
    if judge(sorted_pair_lst, middle):
        high = middle
    else:
        low = middle
print(low) if judge(sorted_pair_lst, low) else print(high)

Solution (Python):
def isok(A_, F_, N_, K_, x):
  _K_ = 0
  for i in range(N_):
    a_ = A_[i]-x//F_[i]
    if a_ > 0:
      _K_ += a_
  if _K_ > K_:
  	return False
  else:
    return True

N, K = map(int, input().split())
A = sorted(list(map(int, input().split())))
F = sorted(list(map(int, input().split())), reverse = True)
ok = 10**12
ng = 0
while abs(ok-ng)>1:
  mid_x = (ok+ng)//2
  if isok(A, F, N, K, mid_x):
    ok = mid_x
  else:
    ng = mid_x
if isok(A, F, N, K, ng):
  print(ng)
else:
  print(ok)

Solution (Python):
import numpy as np

def solve(n, k, aaa, fff):
  aaa = np.sort(aaa)
  fff = np.sort(fff)[::-1]
  
  l = 0
  r = 10**12
  while l<=r:
    m = (l+r)//2
    req = np.clip(aaa - m//fff, 0, None).sum()

    if req <= k:
      r = m-1
    else:
      l = m+1

  return l


N, K = map(int,input().split())
aaa = np.array(list(map(int,input().split())))
fff = np.array(list(map(int,input().split())))

print(solve(N, K, aaa, fff))

Solution (Python):
N,K=map(int,input().split())
A=sorted(map(int,input().split()))
F=sorted(map(int,input().split()))[::-1]

left,right=-1,10**12
while left + 1 < right:
    mid = (left + right)//2
    if sum([max(0,a-mid//f) for a,f in zip(A,F)])>K:
        left = mid
    else:
        right = mid
print(right)

Solution (Python):
def is_ok(x):
    result = 0
    for i in range(N):
        a = A[i]
        t = x // F[i]
        if t < a:
            result += a - t
    return result <= K

N,K = map(int,input().split())
A=list(map(int,input().split()))
F=list(map(int,input().split()))
A.sort()
F.sort(reverse=True)
ok=A[-1]*F[0]
ng=-1
while(ng+1<ok):
  c=ng+(ok-ng)//2
  if is_ok(c):
    ok=c
  else:
    ng=c

print(ok)

Solution (Python):
n,k=map(int,input().split())
arr1=list(map(int,input().split()))
arr1=sorted(arr1)
arr2=list(map(int,input().split()))
arr2=sorted(arr2,reverse=True)
l=-1
r=10**12+1
while r-l!=1:
  m=(r+l)//2
  tmp=0
  for i in range(n):
    if arr1[i]>m//arr2[i]:
      tmp+=(arr1[i]-m//arr2[i])
  if tmp<=k:
    r=m
  else:
    l=m
print(r)

Solution (Python):

import sys

N,K=map(int, sys.stdin.readline().split())
A=map(int, sys.stdin.readline().split())
F=map(int, sys.stdin.readline().split())
A.sort(reverse=True)
F.sort()

max_ans=10**12

def check(temp_ans):
    if temp_ans<0:
        return False
    k=0
    for a,f in zip(A,F):
        if a*f<=temp_ans: continue
        aa=temp_ans/f
        k+=(a-aa)
        if K<k:
            return False
    else:
        return True

h=max_ans
l=-1

while h-l!=1:
    m=(h+l)/2
    if check(m):
        h=m
    else:
        l=m

print h

Solution (Python):

import sys

N,K=map(int, sys.stdin.readline().split())
A=map(int, sys.stdin.readline().split())
F=map(int, sys.stdin.readline().split())
A.sort(reverse=True)
F.sort()

max_ans=A[0]*F[-1]

def check(temp_ans):
    if temp_ans<0:
        return False
    k=0
    for a,f in zip(A,F):
        if a*f<=temp_ans: continue
        aa=temp_ans/f
        k+=(a-aa)
        if K<k:
            return False
    else:
        return True

h=max_ans
l=-1

while h-l!=1:
    m=(h+l)/2
    if check(m):
        h=m
    else:
        l=m

print h

Solution (Python):
import numpy as np
N, K = map(int, input().split())
A = np.array(sorted(list(map(int, input().split()))))
F = np.array(sorted(list(map(int, input().split())), reverse=True))
s = A.sum()
l = -1
r = 10**12
while l+1 < r:
    m = (l+r) // 2 
    
    
    if s - np.minimum(A, m//F).sum() <= K:
      r = m
    else:
      l = m
print(r)

Solution (Python):
n,K=map(int,input().split())
A=list(map(int,input().split()))
F=list(map(int,input().split()))
A.sort(reverse=True)
F.sort()
ng=-1
ok=10**18+1
while ok-ng>1:
             mid=(ng+ok)//2
             k=K
             for a,f in zip(A,F):
                     k-=max(0,a-mid//f)
             if k<0:
                 ng=mid
             else:
                ok=mid
print(ok)

Solution (Python):

n,k=map(int, input().split())
a=list(map(int, input().split()))
f=list(map(int, input().split()))

a.sort()
f.sort()
f.reverse()
x=0
for i in range(n):
    y=a[i]*f[i]
    x=max(x,y)

l=-1
r=x
z=0
while l+1<r:
    mid =(l+r)//2
    for i in range(n):
        if a[i]*f[i]<=mid:
            continue
        else:
            z+=-(-(a[i]*f[i]-mid)//f[i])
    if z<=k:
        r=mid
        z=0
    else:
        l=mid
        z=0
print(r)

Solution (Python):

 
n, k = map(int, input().split())
A = [int(i) for i in input().split()]
A.sort(reverse = True)
F = [int(i) for i in input().split()]
F.sort()
"""
n = 11
k = 14
A = [1,1,2,3,3,4,5,5,5,6,9]
F = [9,9,8,8,7,6,4,3,3,2,2]
"""

 
P = [A[i]*F[i] for i in range(n)]
sum_A = sum(A)
 
def b(p):
    result = 0
    for i in range(n):
        if P[i] > p:
            r = (P[i] - p) // F[i]
            if P[i] - r * F[i] > p:
                r += 1
            result += r
    return result
 
if sum_A <= k: print('0')
else: 
    left = 0
    right = max(P)
    middle = int((left + right) / 2)
    bm = b(middle)
    
    
    
    while right - left > 1:
        
        if bm > k: left = middle
        else: right = middle
            
        middle = int((left + right) / 2)
        bm = b(middle)
 
    if b(left) <= k: print(left)
    else: print(right)

Solution (Python):
import os
import sys
from io import BytesIO

sys.stdin = BytesIO(os.read(0, os.fstat(0).st_size))

n, k = map(int, sys.stdin.readline().split())
a = map(int, sys.stdin.readline().split())
f = map(int, sys.stdin.readline().split())
a.sort()
f.sort(reverse=True)

'''
n, k = 100000, 0
a = range(n)
f = range(n)
a.sort()
f.sort(reverse=True)

print n, k

for i in range(n):
	print 1,
print

for i in range(n):
	print 1,
print
'''


def val(p):
	r = 0
	for i in range(n):
		t = 0 if a[i] * f[i] <= p else a[i] - p // f[i]
		r += t
	return r
		
def bin(l, r):
	if l == r:
		return l
	if l + 1 == r:
		if val(l) <= k:
			return l
		else:
			return r
	t = (l + r) // 2
	if val(t) <= k:
		return bin(l, t)
	else:
		return bin(t, r)
		
R = bin(0, 1000000000000)
print(R)