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 = map(int,input().split())
A = sorted(list(map(int,input().split())))
F = sorted(list(map(int,input().split())),reverse=True)

low = -1
high = 10**12

while high - low > 1:
    score = (low+high)//2
    training = 0
    for i in range(n):
        if A[i]*F[i] > score:
            training += A[i] - score//F[i]
    if training <= k:
        high = score
    else:
        low = score
        
print(high)

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=list(map(int,input().split()))
a=sorted(list(map(int,input().split())))
f=sorted(list(map(int,input().split())),reverse=True)

left = -1
right = 10**18+1
 
 
while right - left > 1:
    mid = left + (right - left) // 2
 
 
    train = k
    for i in range(n):
        req = mid // f[i]
        if req < a[i]:
            train -= a[i] - req
 
 
    if train >= 0:
        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)

ng = -1
ok = 10 ** 12

while ok - ng > 1:
	mid = (ok + ng) // 2
	ctr = 0
	for i in range(N):
		ctr += max(0, A[i] - mid // F[i])
	if ctr <= K:
		ok = mid
	else:
		ng = mid

print(ok)

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

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

Solution (Python):
import numpy as np

n,k = map(int, input().split())
lstA = np.array(sorted(list(map(int, input().split()))))
lstF = np.array(sorted(list(map(int, input().split())), reverse=True))
s = lstA.sum()

left = -1
right = 10**12

while True:
    center = (left+right)//2
    if s-np.minimum(lstA, center//lstF).sum() <=k:
        right = center
    else:
        left = center
    if right <= left+1:
        print(right)
        exit()

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)
ok = 10**12
ng = -1

while ok-ng>1:
  X = (ok+ng)//2
  tmp = 0
  for i in range(N):
    tmp += max(A[i]-X//F[i],0)
  if tmp<=K:
    ok = X
  else:
    ng = X
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)
ok = 10**12
ng = -1

while ok-ng>1:
  X = (ok+ng)//2
  tmp = 0
  for i,e in enumerate(A):
    tmp += max(e-X//F[i],0)
  if tmp<=K:
    ok = X
  else:
    ng = X
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)


ng = -1
ok = 10**12
while ok-ng > 1:
    mid = (ok+ng)//2
    cnt = 0

    for i,e in enumerate(a):    
        cnt += max(0,e-mid//f[i])
    if cnt <= k:
        ok = mid
    else:
        ng = mid

print(ok)

Solution (Python):
import math

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

af = [[] for i in range(n)]
r = 0
for i in range(n):
	af[i] = [a[n-1-i]*f[i], f[i]]
	r = max(r, af[i][0])
af.sort()
af = af[::-1]


l = 0
while l < r:
	c = (l+r)//2
	training = 0
	for e in af:
		if c >= e[0] or k < training:
			break
		training += (e[0]-c + e[1]-1) // e[1]
	if training <= k:
		r = c
	else:
		l = c+1
print(l)

Solution (Python):
def main():
    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()
    a = a[::-1]
    f.sort()
    right = np.max(a*f)
    left = 0
    while right > left:
        middle = (right + left)//2
        if np.sum(np.maximum(a-middle//f, 0)) <= k:
            right = middle
        else:
            left = middle+1
    print(right)
if __name__ == '__main__':
    main()

Solution (Python):
def main():

    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()
    a = a[::-1]
    f.sort()
    right = np.max(a*f)
    left = 0
    while right > left:
        middle = (right + left)//2
        b = 0
        
        if np.sum(np.maximum(a-middle//f, 0)) <= k:
            right = middle
        else:
            left = middle+1

    print(right)
if __name__ == '__main__':
    main()

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+2
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()
f.sort(reverse=True)
lx = -1
rx = a[-1] * f[0]
while rx-lx>1 :
    cx = (lx + rx) // 2
    kk = 0
    for j in range(n):
        kk += max(0, a[j] - cx//f[j])
    if kk <= k:
        rx = cx
    else:
        lx = cx
print(rx)

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()
a = a[::-1]
left = -1
right = np.max(a * f)
while left + 1 < right:
    mid = (left + right) // 2
    if np.sum(np.maximum(a - mid // f, 0)) <= k:
        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)


scale = 42
aim = 2 ** scale -1
gap = 2 ** (scale-1)
while True:
  train = 0
  for i in range(n):
    train += max(0, a[i] - aim//f[i])
  if gap == 0:
    if train <= k:
      print(aim)
    else:
      print(aim+1)
    break
  
  if train <= k:
    aim -= gap
    gap //= 2
  else:
    aim += gap
    gap //= 2

Solution (Python):
import numpy as np
N, K = map(int, input().split())
A = np.array(list(map(int, input().split())))
F = np.array(list(map(int, input().split())))

if sum(A) < K:
    K = sum(A)

A.sort()
F.sort()
F = F[::-1]

left = 0
right = 10 ** 12
while left < right:
    mid = (left + right) // 2
    G = A - (mid // F)
    if G[G>0].sum() <= K:
        right = mid
    else:
        left = mid + 1

print(right)

Solution (Python):
n,k = map(int,input().split())
a = list(map(int,input().split()))
f = list(map(int,input().split()))
f.sort()
a.sort(reverse=True)
x = 0
l = []
for i in range(n):
    l.append(a[i]*f[i])
m = max(l)
nibu = [0,m]
while nibu[0]+1 < nibu[1]:
    p = (nibu[0]+nibu[1])//2
    count = 0
    for i in range(n):
        if p < l[i]:
            count += (l[i]-p)//f[i]
            if (l[i]-p)%f[i] > 0:
                count += 1
    if count > k:
        nibu[0] = p
    else:
        nibu[1] = p
count = 0
p = nibu[0]

for i in range(n):
    if p < l[i]:
        count += (l[i]-p)//f[i]
        if (l[i]-p)%f[i] > 0:
            count += 1
    
if count > k:
    print(nibu[1])
else:
    print(nibu[0])

Solution (Python):
from math import ceil
import sys
sys.setrecursionlimit(10**9)
input = sys.stdin.readline


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

low = 0
high = A[-1]*F[0]

while low <= high:
    mid = (low+high)//2
    train = K
    for a, f in zip(A, F):
        if a*f > mid:
            need_train = ceil((a*f-mid)/f)
            if train >= need_train:
                train -= need_train
            else:
                low = mid+1
                break
    else:
        high = mid-1
print(low)

Solution (Python):
import sys


def solve():
    sys.setrecursionlimit(2000)
    input = sys.stdin.readline
    mod = 10 ** 9 + 7
    n, k = list(map(int, input().rstrip('\n').split()))
    a = list(map(int, input().rstrip('\n').split()))
    f = list(map(int, input().rstrip('\n').split()))
    a.sort()
    f.sort(reverse=True)

    cor_v = 10 ** 13
    inc_v = -1
    while cor_v - inc_v > 1:
        bin_v = (cor_v + inc_v) // 2
        cost = 0
        
        for i in range(n):
            cost += max((a[i] * f[i] - bin_v + f[i] - 1) // f[i], 0)
        
        if cost <= k:
            cor_v = bin_v
        else:
            inc_v = bin_v
    print(cor_v)


if __name__ == '__main__':
    solve()

Solution (Python):
import numpy as np
N, K = map(int, input().split())
A = np.array(list(map(int, input().split())))
F = np.array(list(map(int, input().split())))

if sum(A) < K:
    K = sum(A)

A.sort()
F.sort()
F = F[::-1]

left = 0
right = 10 ** 12
while left < right:
    mid = (left + right) // 2
    sum = 0
    G = A - (mid // F)


    if G[G>0].sum() <= K:
        right = mid
    else:
        left = mid + 1

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)

left, right = -1, a[-1] * f[0]

while right - left > 1:
    mid = (left + right) // 2
    ck = 0
    for i in range(n): 
      ck += max(0, a[i] - mid // f[i])
    if ck <= k: right = mid
    else: left = mid

print(right)

Solution (Python):
import math
import numpy as np


def main():
    s = input().split(" ")
    N = int(s[0])
    K = int(s[1])
    A = np.array([int(a) for a in input().split(" ")])
    F = np.array([int(a) for a in input().split(" ")])
    A = np.sort(A)
    F = np.sort(F)[::-1]
    AF = A * F
    m = np.max(AF)

    if(func(0, AF, F, N, K)):
        print(0)
        return
    a = 0
    b = m
    for aaa in range(m):
        if((b - a) <= 1):
            print(b)
            return
        mid = int((b - a) / 2.) + a
        if(func(mid, AF, F, N, K)):
            b = mid
        else:
            a = mid
    print("???????")


def func(saidai, AF, F, N, K):
    count = np.sum(np.ceil((AF[(AF - saidai) > 0] - saidai) / F[(AF - saidai) > 0]))
    return count <= K


if(__name__ == "__main__"):
    main()

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]

Amax = A[-1]
Fmax = F[0]

x=0
if sum(A) < K:
    x = 0
else:
    xl = 0
    xh = Amax*Fmax
    while xh-xl > 0:
        xm = int((xl+xh)//2)
        AF = A-xm//F 
        if np.sum(AF[AF>0]) > K: 
            xl = xm + 1
        else: 
            xh = xm
    else:
        x = xl
print(x)

Solution (Python):
import numpy as np
from math import ceil

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

A.sort()
F.sort()

if np.sum(A) <= K:
    print(0)
else:
    st = 0
    ed = 10 ** 12
    md = ceil((st + ed) / 2)
    while True:
        if np.sum(A - np.minimum(A, md // F[::-1])) <= K:
            ed = md
        else:
            st = md
        md = ceil((st + ed) / 2)

        if md == ed:
            break

    print(md)

Solution (Python):
import numpy as np
N, K = map(int,input().split())
A = np.array(sorted(map(int,input().split())))
F = np.array(sorted(map(int,input().split()) ,reverse=True))
low,high = -1, int(1e12)
while high-low>1:
  mid = (high+low)//2
  k = (A-np.minimum(A,mid//F)).sum()
  if k>K: low = mid
  else: high = mid
print(high)

Solution (Python):
import numpy as np
N,K = map(int,input().split())
A = np.array(list(map(int,input().split())))
F = np.array(list(map(int,input().split())))
A = np.sort(A)
F = np.sort(F)[::-1]
Asum = A.sum()

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

left = -1
right = np.amax(A * F)

while right - left > 1:
    mid = (right + left)//2
    if test(mid) == 1:
        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)

left, right = -1, a[-1] * f[0]

while right - left > 1:
    mid = (left + right) // 2
    ck = 0
    for i in range(n): ck += max(0, a[i] - mid // f[i])
    if ck <= k: right = mid
    else: left = mid

print(right)

Solution (Python):
n,k = map(int,input().split())
alist = list(map(int,input().split()))
flist = list(map(int,input().split()))
alist.sort()
flist.sort(reverse = True)
L = -1
R = 10 ** 18
while R-1 > L:
  mid = (R +L)//2
  count = 0
  loop_count = 0
  for i in flist:
    if alist[loop_count] > mid // i:
      count += alist[loop_count] - mid // i
    loop_count += 1
  if count > k:
    L = mid
  else:
    R = mid
print(R)

Solution (Python):
from collections import Counter,defaultdict,deque
import sys,bisect,math,itertools,string,queue
from heapq import heappop, heappush
sys.setrecursionlimit(10**8)
mod = 10**9+7
def inp(): return int(sys.stdin.readline())
def inpl(): return list(map(int, sys.stdin.readline().split()))
def inpl_str(): return list(sys.stdin.readline().split())
def inpln(n): return list(int(sys.stdin.readline()) for i in range(n))

n,k = inpl()
a = inpl()
f = inpl()
a.sort()
f.sort(reverse=True)
l = -1
r = 10**18

def sol(x):
    cnt = 0
    for i in range(n):
        cnt += max(0, a[i] - x//f[i])
    
    if cnt <= k:
        return True
    else:
        return False

while l + 1 < r:
    mid = (l+r)//2
    if sol(mid):
        r = mid
    else:
        l = mid
    
print(r)

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

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

t_max = A[-1] * F[0]
t_min = -1

while t_max > t_min + 1:
    t_mid = (t_max + t_min) // 2
    K_tmp = np.sum(np.maximum(A - t_mid // F, 0))
    if K_tmp <= K:
        t_max = t_mid
    else:
        t_min = t_mid

print(t_max)

Solution (Python):
import numpy as np
N, train_max = map(int, input().split())
members = np.sort(list(map(int, input().split())))
members_sum = members.sum()
foods = np.sort(list(map(int, input().split())))[::-1]

inferenced_time_max = int(1e+6 * 1e+6)
inferenced_time_min = -1

while inferenced_time_max > inferenced_time_min+1:
  inferenced_time = (inferenced_time_max + inferenced_time_min) // 2
  inferenced_members = np.minimum(members, inferenced_time // foods)
  if members_sum - inferenced_members.sum() <= train_max:
    inferenced_time_max = inferenced_time
  else:
    inferenced_time_min = inferenced_time

print(inferenced_time_max)

Solution (Python):
import numpy as np

N, K = map(int, input().split())
A = np.array(sorted(list(map(int, input().split()))))
f=list(map(int,input().split()))
ff=sorted(f, reverse=True)
F=np.array(ff)



left = - 1
right = 10**12

'''
l=10//F
print(A)
print(l)
print(A[A>l])
print(A[A>l].sum())
'''

def f(x):
    l = x//F
    return A[A > l].sum() <= K + l[A > l].sum()
    

 
while right - left > 1:
    mid = (left + right)//2
    if f(mid):
        right = mid
    else:
        left = mid
    
print(right)

Solution (Python):
def isOK(score):
    min_cost = sum_a - sum([min(A,score // F) for A,F in zip(a,f)])
    if min_cost <= k:
        return True
    else:
        return False


def binary_search():
    ok = 10 ** 12 + 100
    ng = -1
    while abs(ok-ng) > 1:
        mid = (ok+ng)//2
        if isOK(mid):
            ok = mid
        else:
            ng = mid
    return ok



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

sum_a = sum(a)
ans = binary_search()
print(ans)

Solution (Python):
def main():
    
    
    
    
    
    
    
    
    
    
    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 = 10**12
    ng=-1

    while ok-ng>1:
        mid=(ok+ng)//2
        cnt=0
        for x,y in enumerate(a):
            cnt+=max(0,y-mid//f[x])
        if cnt>k:
            ng=mid
        else:
            ok=mid
    print(ok)
main()

Solution (Python):
n,k=map(int,input().split())
a=[int(i) for i in input().split()]
f=[int(i) for i in input().split()]
a.sort()
f.sort(reverse=True)
w=[0,0]
for i in range(n):
    w[1]=max(w[1],a[i]*f[i])
x=50
while x>0:
    x-=1
    ws=(w[0]+w[1])//2
    p=k
    for i in range(n):
        if a[i]*f[i]>ws and p<a[i]-ws//f[i]:
            p=-1
            break
        elif a[i]*f[i]>ws:
            p-=a[i]-ws//f[i]
    if p>=0:
        w[1]=ws
    else:
        w[0]=ws
print(w[1])

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):
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+2

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):
(_,K),*T=[map(int,t.split())for t in open(0)]
A,B=map(sorted,T)
d=[2**40,0]
exec("i=sum(d)//2;d[sum(max(0,a-i//b)for a,b in zip(A,B[::-1]))>K]=i;"*41)
print(d[0])

Solution (Python):
(_,K),*T=[map(int,t.split())for t in open(0)]
A,B=map(sorted,T)
d=[2**40,0]
exec("i=sum(d)//2;d[-sum(min(0,i//b-a)for a,b in zip(A,B[::-1]))>K]=i;"*41)
print(d[0])

Solution (Python):
(_,K),*T=[map(int,t.split())for t in open(0)]
A,B=map(sorted,T)
d=[0,2**40]
exec("i=sum(d)//2;d[-sum(min(0,i//b-a) for a,b in zip(A,B[::-1]))<=K]=i;"*41)
print(d[1])

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



import numpy as np



















def main():
	N,K=map(int,input().split())
	AF=np.array(read().split(),np.int64)
	A,F=np.split(AF,2)
	A.sort()
	F.sort()
	F=F[::-1]
	
	lt=0
	rt=10**12+1
	
	Asum=A.sum()
	
	while rt-lt>1:
		mid=(rt+lt)//2
		if Asum-np.minimum(A,mid//F).sum()<=K:
			rt=mid
		else:
			lt=mid
	print(rt if Asum-K>0 else 0)
	
if __name__ == '__main__':
	main()

Solution (Python):
N, K = list(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


def ok(c):
    s = 0
    for a, f in zip(A, F):
        s += max(0, a - c//f)
    return s <= K


while r - l > 1:
    c = (l+r)//2
    if ok(c):
        r = c
    else:
        l = c

print(r)

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



import numpy as np



















def main():
	NKAF=np.array(read().split(),np.int64)
	N=NKAF[0]
	K=NKAF[1]
	AF=NKAF[2:]
	A,F=np.split(AF,2)
	A.sort()
	F.sort()
	F=F[::-1]
	
	lt=0
	rt=10**12+1
	
	Asum=A.sum()
	
	while rt-lt>1:
		mid=(rt+lt)//2
		if Asum-np.minimum(A,mid//F).sum()<=K:
			rt=mid
		else:
			lt=mid
	print(rt if Asum-K>0 else 0)
	
if __name__ == '__main__':
	main()

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



import numpy as np



















def main():
	NKAF=np.array(read().split(),np.int64)
	N=NKAF[0]
	K=NKAF[1]
	AF=NKAF[2:]
	A,F=np.split(AF,2)
	A.sort()
	F.sort()
	F=F[::-1]
	
	lt=0
	rt=10**12+1
	
	Asum=sum(A)
	
	while rt-lt>1:
		mid=(rt+lt)//2
		if Asum-np.minimum(A,mid//F).sum()<=K:
			rt=mid
		else:
			lt=mid
	print(rt if Asum-K>0 else 0)
	
if __name__ == '__main__':
	main()

Solution (Python):
N, K = list(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 = A[-1] * F[0]


def ok(c):
    s = 0
    for a, f in zip(A, F):
        s += max(0, a - c//f)
    return s <= K


while r - l > 1:
    c = (l+r)//2
    if ok(c):
        r = c
    else:
        l = c

print(r)

Solution (Python):
(_,K),*T=[map(int,t.split())for t in open(0)]
A,B=map(sorted,T)
d=[0,2**40]
exec("i=sum(d)//2;d[-sum(min(0,i-a*b)//b for a,b in zip(A,B[::-1]))<=K]=i;"*41)
print(d[1])

Solution (Python):
(_,K),*T=[map(int,t.split())for t in open(0)]
A,B=map(sorted,T)
m,M,i=0,2**40,1
exec("i,M,m=((i+m)//2,i,m) if -sum(min(0,i-a*b)//b for a,b in zip(A,B[::-1]))<=K else((i+M)//2,M,i);"*41)
print(M)

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

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

Solution (Python):
N,K=map(int,input().split())
X=[(b,a*b)for a,b in zip(sorted(list(map(int,input().split()))),sorted(list(map(int,input().split())))[::-1])]
m,M,i=0,2**40,1
exec("i,M,m=((i+m)//2,i,m) if -sum(min(0,i-c)//b for b, c in X)<=K else((i+M)//2,M,i);"*50)
print(M)

Solution (Python):
import math
N,K=map(int,input().split())
X=[(b,a*b)for a,b in zip(sorted(list(map(int,input().split()))),sorted(list(map(int,input().split())))[::-1])]
m,M,i=0,10**12,1
exec("i,M,m=((i+m)//2,i,m) if sum(math.ceil(max(0,c-i)/b)for b, c in X)<=K else((i+M)//2,M,i);"*50)
print(M)

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)

K_list = [0] * N
K_sum = 0

A_sum = 0

for i in range(N):
    A_sum += A[i]

if A_sum <= K:
    print(0)

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

    while right - left > 1:
        K_sum = 0
        mid = (right + left) // 2
        for i in range(N):
            if A[i] * F[i] > mid:
                K_list[i] = A[i] - mid // F[i]
                K_sum += K_list[i]

        if K_sum > K:
            left = mid
        else:
            right = mid
    print(right)

Solution (Python):
import sys
import numpy as np
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 7)


def main():
    N, K = map(int, input().split())
    A = np.array(list(map(int, input().split())))
    F = np.array(list(map(int, input().split())))

    A.sort()
    F.sort()
    F = F[::-1]
    Asum = A.sum()

    left = -1
    right = 10 ** 12
    while left+1 < right:
        mid = (left+right) // 2
        if Asum - np.minimum(A, mid//F).sum() <= K:
            right = mid
        else:
            left = mid
    print(right)


if __name__ == '__main__':
    main()
    1

Solution (Python):
import math
N,K=map(int,input().split())
X=[(b,a*b)for a,b in zip(sorted(list(map(int,input().split()))),sorted(list(map(int,input().split())))[::-1])]
min_i, max_i, index = 0, 10**12, 1
while True:
    index, max_i, min_i = ((index-1 + min_i)//2, index-1, min_i) if sum(math.ceil(max(0,c-index)/b)for b, c in X)<=K else((index+1 + max_i)//2, max_i, index+1)
    if min_i > max_i:
        print(min_i)
        break

Solution (Python):
import math
N, K = map(int, input().split())
BCs = [(b,a*b) for a,b in zip(sorted(list(map(int, input().split()))), sorted(list(map(int, input().split())))[::-1])]

def f(target):
    return sum(math.ceil(max(0, c - target)/b)for b, c in BCs)<=K

if __name__ == '__main__':
    min_i, max_i, index = 0, 10**12, 1
    while True:
        index, max_i, min_i = ((index-1 + min_i)//2, index-1, min_i) if f(index) else ((index+1 + max_i)//2, max_i, index+1)
        if min_i > max_i:
            print(min_i)
            break

Solution (Python):
import math
N, K = map(int, input().split())
As = sorted(list(map(int, input().split())))
Bs = sorted(list(map(int, input().split())))[::-1]
Cs = [a*b for a, b in zip(As, Bs)]
BCs = list(zip(Bs, Cs))

def func(target):
    r = 0
    for b, c in BCs:
        r += math.ceil(max(0, c - target) / b)
    return r <= K

if __name__ == '__main__':
    min_i, max_i, index = 0, max(Cs)+1, 1
    while True:
        if func(index):
            index, max_i = (index-1 + min_i)//2, index-1
        else:
            index, min_i = (index+1 + max_i)//2, index+1
        if min_i > max_i:
            print(min_i)
            break

Solution (Python):

from collections import defaultdict,deque
from heapq import heappush, heappop
from bisect import bisect_left, bisect_right
import sys, random, itertools, math
sys.setrecursionlimit(10**5)
input = sys.stdin.readline
sqrt = math.sqrt
def LI(): return list(map(int, input().split()))
def LF(): return list(map(float, input().split()))
def LI_(): return list(map(lambda x: int(x)-1, input().split()))
def II(): return int(input())
def IF(): return float(input())
def LS(): return list(map(list, input().split()))
def S(): return list(input().rstrip())
def IR(n): return [II() for _ in range(n)]
def LIR(n): return [LI() for _ in range(n)]
def FR(n): return [IF() for _ in range(n)]
def LFR(n): return [LI() for _ in range(n)]
def LIR_(n): return [LI_() for _ in range(n)]
def SR(n): return [S() for _ in range(n)]
def LSR(n): return [LS() for _ in range(n)]
mod = 1000000007
inf = float('INF')


def A():
    return


def B():
    return


def C():
    return


def D():
    return


def E():
    def solve(m):
        a1 = a[::-1]
        f1 = f[::1]
        res = 0
        for i in range(n):
            if a1[i] * f1[i] <= m:
                continue
            k = m // f1[i]
            res += a1[i] - k
            if res > K:
                return False
        return True

    n, K = LI()
    a = LI()
    a.sort()
    f = LI()
    f.sort()
    ok = max(a) * max(f)
    ng = -1
    while ok - ng > 1:
        mid = (ok + ng) // 2
        if solve(mid):
            ok = mid
        else:
            ng = mid
    print(ok)
    return


def F():
    return



if __name__ == '__main__':
    E()

Solution (Python):
import numpy as np

def main():
    N,K = map(int, input().split())
    A = np.array(input().split(), np.int64)
    F = np.array(input().split(), np.int64)

    if sum(A) <= K:
        print(0)
        exit()

    A.sort()
    F.sort()
    A = A[::-1]
    
    cost = A * F
    down = -1
    up = np.max(cost)
    while up > down + 1:
        mid = (down + up) // 2
        if np.sum(np.where(cost > mid, np.ceil((cost - mid) / F), 0)) <= K:
            up = mid
        else:
            down = mid
    
    print(up)
    

if __name__ == "__main__":
    main()

Solution (Python):
import math
N, K = map(int, input().split())
As = sorted(list(map(int, input().split())))
Bs = sorted(list(map(int, input().split())))[::-1]
Cs = [a*b for a, b in zip(As, Bs)]
BCs = list(zip(Bs, Cs))

def func(target):
    r = 0
    for b, c in BCs:
        r += math.ceil(max(0, c - target) / b)
    return r <= K

if __name__ == '__main__':
    min_i, max_i, index = 0, max(Cs)+1, 1
    while True:
        if func(index):
            index, max_i = (index-1 + min_i)//2, index-1
        else:
            index, min_i = (index+1 + max_i)//2, index+1
        if min_i > max_i:
            print(min_i)
            break

Solution (Python):
n,k=list(map(int,input().split()))
a=sorted(list(map(int,input().split())))
f=sorted(list(map(int,input().split())),reverse=True)
b = [a[i]*f[i] for i in range(n)]

def judgement(x):
    judge = -1
    cnt = 0
    for i in range(n):
        if b[i]>x:
            cnt += -((x-b[i])//f[i])
        if cnt > k:
            judge = False
            break
    if cnt <= k:
        judge = True
    return judge

low=0
high=max(b)
while low<high:
    mid = (low + high)//2
    if judgement(mid) == False:
        low=mid+1
    else:
        high=mid
print(low)

Solution (Python):
import math
n,k = map(int,input().split())
A = list(map(int,input().split()))
F = list(map(int,input().split()))
A.sort()
F.sort(reverse = True)
e = [0]*n
for i in range(n):
    e[i] = A[i]*F[i]
    
def s(e,x):
    kk=0
    for i in range(n):
        if e[i] < x:
            continue
        else:
            kk += math.ceil((e[i]-x)/F[i]) 
    if kk > k:
        return False
    else:
        return True


sma = 0
big = A[-1]*F[0]

while big != sma:
    mid = (big+sma)//2
    if s(e,mid):
        big = mid
    else:
        sma = mid + 1
print(sma)

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

_n, _k = map(int, input().split())
alist = [int(item) for item in input().split()]
flist = [int(item) for item in input().split()]


def chker(costs, diffs, max_k):
	costs = np.sort(costs)[::-1]
	diffs = np.sort(diffs)
	
	_min, _max = 0, 10 ** 12
	while _min < _max:
		_mid = (_min + _max) // 2
		cnt = costs - _mid // diffs
		if cnt[cnt > 0].sum() <= max_k:
			_max = _mid
		else:
			_min = _mid + 1


	print(_min)


chker(alist, flist, _k)

Solution (Python):
import numpy as np
N,K = [int(x) for x in input().split()]
A = np.array([int(x) for x in input().split()])
F = np.array([int(x) for x in input().split()])
A.sort()
Asum=np.sum(A)
F.sort();F=F[::-1]
left=-1 
right=10**20 
while left+1<right:
  mid =(left+right)//2
  if Asum-np.minimum(A,mid//F).sum()<=K:
    right=mid
  else:
    left=mid
print(right)