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([int(a) for a in input().split()])
F = sorted([int(f) for f in input().split()], reverse=True)
INF = 10**12+10

l = -1
r = INF
while r - l > 1:
    c = (l + r) // 2
    SUM_B = 0
    for i in range(N):
        SUM_B += max(0, A[i] - c//F[i])
    if SUM_B <= K:
        r = c
    else:
        l = c

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)

def det(x):
    KK = K
    for i in range(N):
        if int(max(0,A[i]-x/F[i])) == max(0,A[i]-x/F[i]):
            KK -= int(max(0,A[i]-x/F[i]))
        else:
            KK -= int(max(0,A[i]-x/F[i])) + 1
        if KK < 0:
            return False
        
    return True

if det(0):
    print(0)
else:
    R = [0,10**12]

    while R[1] - R[0] > 1:
        if det(int((R[0]+R[1])//2)):
            R[1] = int((R[0]+R[1])//2)
        else:
            R[0] = int((R[0]+R[1])//2)
        

    print(R[1])

Solution (Python):
def f(x):
    cnt=0
    for i in range(N):
        num=x//F[i]
        if A[i]>num:
            cnt+=A[i]-num
    return cnt

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

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

low=0
high=10**12+1
while high-low>0:
    mid=(high+low)//2
    xxx=f(mid)
    if xxx<=K:
        high=mid
    else:
        if low==mid:
            low=high
        else:
            low=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)

bh = 10**12
bl = 0
m = 10**6
while True:
    t = K
    for i in range(len(A)):
        if A[i]*F[i] > m:
            t -= A[i] - int(m / F[i])
            if t < 0:
                break
    if t >= 0:
        bh = m
        m = (bh + bl) // 2
    else:
        bl = m + 1
        m = (bh + bl) // 2
    if bh == bl:
        print(bh)
        exit(0)

Solution (Python):
import numpy as np
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)
A = np.array(A)
F = np.array(F)
Asum = A.sum()
M = np.max(A*F)

l = -1
r = M+1
while l+1<r:
  s = (l+r)//2
  cnt = Asum - np.minimum(A, s//F).sum()
  if cnt>K:
    l = s
  else:
    r = s

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)
M = 0
for i in range(N):
  if A[i]*F[i]>M:
    M = A[i]*F[i]

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

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)
l=-1
r=10**12+10
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)

Solution (Python):
import sys
import numpy as np

sr = lambda: sys.stdin.readline().rstrip()
ir = lambda: int(sr())
lr = lambda: list(map(int, sr().split()))


N, K = lr()
A = np.array(lr())
F = np.array(lr())
A.sort()
F = np.sort(F)[::-1]

def check(x):
    count = np.maximum(0, (A - (x // F))).sum()
    return count <= K

left = 10 ** 12 
right = -1 
while left > right + 1:
    mid = (left+right) // 2
    if check(mid):
        left = mid
    else:
        right = mid

print(left)

Solution (Python):
from math import ceil

def check(N_:int,S_:list,F_:list,upper:int,K_:int)->bool:
    
    cnt = 0
    for i in range(N_):
        s = S_[i]
        if s > upper:
            cnt += ceil((s - upper)/F_[i])
            if cnt > K_:
                return False
    return True


def main():
    N,K = map(int,input().split())
    A = list(map(int,input().split()))
    F = list(map(int,input().split()))
    A.sort(reverse = True)
    F.sort()
    S = [f*a for f,a in zip(F,A)]
    right = max(S)
    left = -1
    while left + 1 < right:
        mid = (right + left) // 2
        if mid == right:
            break
        if check(N,S,F,mid,K):
            right = mid
        else:
            left = mid
    print(right)
    return

if __name__ == "__main__":
    main()

Solution (Python):
import sys

sys.setrecursionlimit(10 ** 6)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep="\n")
def IS(): return sys.stdin.readline()[:-1]
def II(): return int(sys.stdin.readline())
def MI(): return map(int, sys.stdin.readline().split())
def LI(): return list(map(int, sys.stdin.readline().split()))
def LI1(): return list(map(int1, sys.stdin.readline().split()))
def LII(rows_number): return [II() for _ in range(rows_number)]
def LLI(rows_number): return [LI() for _ in range(rows_number)]
def LLI1(rows_number): return [LI1() for _ in range(rows_number)]

def main():
	N,K = MI()
	A = LI();A.sort();
	F = LI();F.sort(reverse=True);
	upper_X = -1
	for i in range(N):
		upper_X = max(A[i]*F[i], upper_X)


	def BinarySearch(upper_X, lower_X):
		X = upper_X//2 
		candidate = upper_X
		while upper_X > lower_X:
			deduct = 0
			for i in range(N):
				n = A[i]-X//F[i]
				deduct += n if n>=1 else 0
			if(K < deduct):
				lower_X = X
				if(upper_X - lower_X) <= 1: break
			else:
				candidate = X
				upper_X = X
			X = (lower_X+upper_X)//2
		return candidate

	print(BinarySearch(upper_X,0))


main()

Solution (Python):
def main():
    N, K = (int(i) for i in input().split())
    A = [int(i) for i in input().split()]
    F = [int(i) for i in input().split()]
    A.sort()
    F.sort(reverse=True)
    ma = 0
    for a, f in zip(A, F):
        ma = max(ma, a*f)

    def is_ok(mid):
        need = 0
        for a, f in zip(A, F):
            if mid < a*f:
                need += (a - mid//f)
        if need <= K:
            return True
        else:
            return False

    def binary_search_meguru():
        left = -1
        right = ma + 1
        while right - left > 1:
            mid = left + ((right - left) // 2)
            if is_ok(mid):
                right = mid
            else:
                left = mid
        return right
    print(binary_search_meguru())


if __name__ == '__main__':
    main()

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

def f(x):
    ans = 0
    for i,j in zip(A, F):
        ans += (i*j-x+j-1)//j if i*j-x>=0 else 0
    return ans<=K

l, r = -1, 10**18+1
while r-l>1:
    mid = (r+l)//2
    if f(mid):
        r = mid
    else:
        l = mid

print(r)

Solution (Python):
N,K = map(int,input().split())
A = [int(x) for x in input().split()]
F = [int(x) for x in input().split()]
A.sort()
F.sort(reverse=True)
AF =  [A[i]*F[i] for i in range(N)]
maxAF = max(AF)

ans = maxAF
left = 0
right = maxAF
while True:
    mid = (left + right)//2
    dis = 0
    syugyo = 0
    for i in range(N):
        af = AF[i]
        if af > mid:
            dis += af-mid
            amari = (af-mid)%F[i]
            count = (af-mid)//F[i]
            if amari == 0:
                syugyo += count
            else:
                syugyo += count +1
    if syugyo > K:
        if right-mid == 1:
            ans = right
            break
        else:
             left = mid
    else:
        if mid-left == 1:
            ans = mid
            break
        else:
            right = mid
if sum(A) <= K:
    ans = 0
print(ans)

Solution (Python):
import numpy as np


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

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

    if K >= np.sum(A)*N:
        print(0)
        exit()

    min_time = 0
    max_time = A[-1] * F[0]

    while max_time != min_time:
        tgt_time = (min_time + max_time)//2
        ideal_a = np.floor(tgt_time*np.ones(N)/F)
        cost = A - ideal_a
        require_k = np.sum(cost[cost > 0])
        if require_k <= K:
            max_time = tgt_time
        else:
            min_time = tgt_time+1

    print(int(max_time))


if __name__ == "__main__":
    main()

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


def C(x):
    train = np.maximum(0, A - x // F).sum()
    return train <= K


left = -1
right = 10 ** 12 + 1
while right > left + 1:
    mid = (right + left) // 2
    if C(mid):  
        right = mid
    else:
        left = mid

ans = right
print(ans)

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

import numpy as np

def main():
  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))
  def is_time(x):
    c = np.maximum(A - x//F, 0).sum()
    if c <= k:
      return True
    return False
  ng = -1
  ok = max(A*F)
  while ok - ng > 1:
    m = (ng + ok)//2
    if is_time(m):
      ok = m
    else:
      ng = m
  print(ok)
  
if __name__ == "__main__":
  main()

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

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

A = sorted(A)
F = sorted(F)[::-1]

left = -1
right = max(A) * max(F)

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

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

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

A = sorted(A)
F = sorted(F)[::-1]

left = -1
right = 10 ** 18

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

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



ok, ng = 10 ** 12 + 1, -1
while ok - ng > 1:
    x = (ok + ng) // 2

    need_training = 0
    for a, f in zip(A, F):
        need_training += max(0, a - x // f)

        if need_training > K:
            ng = x
            break
    else:
        ok = x

print(ok)

Solution (Python):










































import numpy as np
n, k = map(int, input().split())

A = np.array(input().split(), np.int)
F = np.array(input().split(), np.int)

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

left = -1 
right = (A * F).sum()

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

print(right)

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()

C = [None] * N
for i, (a, f) in enumerate(zip(A, F)):
    C[i] = (a * f, f)


def solve(x):
    global K, N
    t = 0
    for c, f in C:
        temp = ((c - x) + f - 1) // f
        t += max(0, temp)
        if t > K:
            result = False
            break
    else:
        result = True
    return result


ok = A[0] * F[N - 1]
ng = -1
while abs(ok - ng) > 1:
    mid = (ok + ng) // 2
    if solve(mid):
        ok = mid
    else:
        ng = mid


print(ok)

Solution (Python):
import sys
import bisect
import math
input = sys.stdin.readline
N, K = map(int, input().split())
A = list(map(int, input().split()))
F = list(map(int, input().split()))

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

B = [(A[i]*F[i], F[i]) for i in range(N)]
B.sort(reverse=True)
L = 0
R = B[0][0]
if sum(A) <= K:
    print(0)
    exit(0)
while(1):
    ans = (L+R) // 2
    flag = True
    tmp = 0
    for i in range(N):
        tmp += math.ceil(max(B[i][0] - ans, 0) / B[i][1])
        if tmp > K:
            flag = False
            break
    if flag:
        R = ans
    else:
        L = ans
    if L == R or L+1 == R:
        print(R)
        break

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)

def check(v):
    ans = 0
    for i in range(N):
        ans += max(A[i] - v//F[i],0)
    return ans<=K

if check(0):
    print(0)
else:
    l = 0
    r = 10**12 + 1
    while r-l>1:
        if check((l+r)//2):
            r = (l+r)//2
        else:
            l = (l+r)//2
    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)
l = -1
r = 10 ** 13
while r - l > 1:
  m = (l + r) // 2
  if sum([(a - m // f) if a * f > m else 0 for a, f in zip(A, F)]) <= k:
    r = m
  else:
    l = m
    
print(r)

Solution (Python):
from math import ceil

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

def is_valid(A, F, K, T):
    for a, f in zip(A, F):
        if a*f > T:

            k = ceil(a - T/f)
            if k <= K:
                K -= k
            else:
                return False
    return True

def solve(N, K, A, F):
    i = 0
    left, right = 0, 10**12

    while left < right:
        mid = (left + right) // 2

        if is_valid(A, F, K, mid):
            right = mid
        else:
            left = mid + 1
    
    if is_valid(A, F, K, mid-1) and (not is_valid(A, F, K, mid)):
        return mid-1
    elif is_valid(A, F, K, mid):
        return mid
    else:
        return mid+1

print(solve(N, K, A, F))

Solution (Python):

from bisect import *
from collections import *
from heapq import *



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 main(x):
    _K=K
    for i in range(N):
        a=A[i]-x//F[i]
        if a>0:
            _K-=a
            if _K<0:
                return(0)
    return(1)


end=10**12
if main(0):
    print(0)
    exit()
else:
    st=0

while end-st>1:
    now=(end+st)//2
    if main(now):
        end=now
    else:
        st=now

if main(st):
    print(st)
else:
    print(end)

Solution (Python):
def main():
    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]

    if K >= np.sum(A)*N:
        print(0)
        exit()
    ma = A[-1]*F[0]
    mi = 0
    A = A*F
    while ma != mi:
        tgt = (ma + mi)//2
        tmp = np.ceil((A-tgt)/F)
        if np.sum(tmp[tmp>0]) <= K:
            ma = (ma + mi)//2
        else:
            mi = (ma + mi)//2+1
    print(ma)
if __name__ == '__main__':
    main()

Solution (Python):
def main():
    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]
    mul = A*F
    if K >= np.sum(A)*N:
        print(0)
        exit()

    ma = A[-1]*F[0]
    mi = 0
    while ma != mi:
        tgt = (ma + mi)//2
        num = np.sum(np.maximum(0,(mul-tgt+F-1)//F))
        if num <= K:
            ma = (ma + mi)//2
        else:
            mi = (ma + mi)//2+1
    print(ma)
if __name__ == '__main__':
    main()

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]
mul = A*F
if K >= np.sum(A)*N:
    print(0)
    exit()

ma = A[-1]*F[0]
mi = 0
while ma != mi:
    tgt = (ma + mi)//2
    tmp = np.ceil((mul-tgt)/F)
    num = np.sum(tmp[tmp>0])
    if num <= K:
        ma = (ma + mi)//2
    else:
        mi = (ma + mi)//2+1
print(ma)

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]
mul = A*F
if K >= sum(A)*N:
    print(0)
    exit()

ma = 2**40
mi = 0
while ma != mi:
    tgt = (ma + mi)//2
    tmp = np.ceil((mul-tgt)/F)
    num = np.sum(tmp[tmp>0])
    if num <= K:
        ma = mi + (ma - mi)//2
    else:
        mi = mi + (ma - mi)//2+1
print(ma)

Solution (Python):
def is_ok(x):
    trainings = 0
    for i in range(N):
        t = A[i] - x // F[i]
        if t > 0:
            trainings += t
    return trainings <= 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)

ng = -1
ok = A[-1] * F[0]
while ok - ng > 1:
    m = ng + (ok - ng) // 2
    if is_ok(m):
        ok = m
    else:
        ng = m
print(ok)

Solution (Python):
import math
N,K = map(int,input().split())
A = sorted(list(map(int,input().split())))
F = sorted(list(map(int,input().split())),reverse=True)
high = 0
for i in range(N):
    high = max(high,A[i]*F[i])
low = -1
while high-low>1:
    mid = (high+low)//2
    flag = 1
    T = K
    for i in range(N):
        if A[i]*F[i]<=mid:continue
        else:
            T -= math.ceil(A[i]-mid/F[i])
            if T<0:
                flag = 0
                break
    if flag==1:
        high = mid
    else:
        low = mid
print(high)

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

A = sorted(A)[::-1]
F = sorted(F)

sumA = sum(A)

if sumA <= K:
    print(0)
else:
    maxC = 0
    for i in range(N):
        tmp = A[i]*F[i]
        if maxC < tmp:
            maxC = tmp
    L = 0
    R = maxC
    visited = {}
    visited[maxC]=True
        
    while 1:
        nowC = (L+R)//2
        nowA = []
        for i in range(N):
            nowA.append(nowC//F[i])
        shugyou = 0
        for i in range(N):
            shugyou += max(A[i]-nowA[i],0)
        if shugyou <= K:
            visited[nowC] = True
            R = nowC
            if (nowC-1) in visited:
                if visited[nowC-1] == False:
                    ans = nowC
                    break
        else:
            visited[nowC] = False
            L = nowC
            if (nowC+1) in visited:
                if visited[nowC+1] == True:
                    ans = nowC+1
                    break
                
        if nowC == 0:
            if visited[nowC]==True:
                ans = 0
                break
    print(ans)

Solution (Python):
import math,string,itertools,fractions,heapq,collections,re,array,bisect,sys,copy,functools
import time,random

sys.setrecursionlimit(10**7)
inf = 10**20
eps = 1.0 / 10**10
mod = 10**9+7
mod2 = 998244353
dd = [(-1,0),(0,1),(1,0),(0,-1)]
ddn = [(-1,0),(-1,1),(0,1),(1,1),(1,0),(1,-1),(0,-1),(-1,-1)]

def LI(): return list(map(int, sys.stdin.readline().split()))
def LLI(): return [list(map(int, l.split())) for l in sys.stdin.readlines()]
def LI_(): return [int(x)-1 for x in sys.stdin.readline().split()]
def LF(): return [float(x) for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def I(): return int(sys.stdin.readline())
def F(): return float(sys.stdin.readline())
def S(): return input()
def pf(s): return print(s, flush=True)
def pe(s): return print(str(s), file=sys.stderr)
def JA(a, sep): return sep.join(map(str, a))
def JAA(a, s, t): return s.join(t.join(map(str, b)) for b in a)

def bs(f, mi, ma):
    mm = -1
    while ma > mi:
        mm = (ma+mi) // 2
        if f(mm):
            mi = mm + 1
        else:
            ma = mm
    if f(mm):
        return mm + 1
    return mm

def main():
    n,k = LI()
    a = sorted(LI())
    b = sorted(LI(), reverse=True)
    if sum(a) <= k:
        return 0

    def f(i):
        t = 0
        for ai,bi in zip(a,b):
            u = i // bi
            if ai > u:
                t += ai - u
        return t > k

    r = bs(f,0,10**12)

    return r


print(main())

Solution (Python):
from math import ceil
n,k=map(int,input().split())
a=sorted(list(map(int,input().split())))
f=sorted(list(map(int,input().split())),reverse=True)
l=[]
for i in range(n):
  l.append([f[i]*a[i],a[i],f[i]])
l.sort()
ng=-1
ok=l[n-1][0]
while ok-ng>1:
  mid=(ok+ng)//2
  cnt=0
  for i in range(n):
    if l[i][0]>mid:
      cnt+=ceil((l[i][0]-mid)/l[i][2])
  if cnt<=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 ok(p):
  result = 0
  for i in range(n):
    result += max(a[i]-p//f[i],0)
  if result <= k:
    return True
  return False

L = 0
U = a[-1]*f[0]
while U-L >= 1:
  M = (U+L)//2
  if ok(M):
    U = M
  else:
    L = M+1
    
print(U)

Solution (Python):
n, k = map(int, input().split())
a = sorted(list(map(int, input().split())))
f = sorted(list(map(int, input().split())))[::-1]
r = 10**12+1
l = -1
while r - l > 1:
    s = k
    mid = (r + l)//2
    for i, j in zip(a, f):
        if mid < i*j:
            s -= i-mid//j
    if s < 0:
        l = mid
    else:
        r = mid

print(r)

Solution (Python):
def p_e():
    n, k = map(int, input().split())
    *A, = map(int, input().split())
    *F, = map(int, input().split())
    A.sort()
    F.sort(reverse=True)

    def check(x):
        count = 0
        for a, f in zip(A, F):
            count += max(a - x // f, 0)
        return count <= k

    max_num = 0
    for a, f in zip(A, F):
        if max_num < a * f:
            max_num = a * f
    l, h = 0, max_num
    while l <= h:
        mid = (l + h) // 2
        if check(mid):
            h = mid - 1
        else:
            l = mid + 1
    print(h + 1)
    
p_e()

Solution (Python):
N,K = map(int,input().split())
A = list(map(int,input().split()))
F = list(map(int,input().split()))
A.sort()
F.sort()
suma = sum(A)
u = 10**12
d = 0
for i in range(50):
    x = (u + d)//2
    s = 0
    for i in range(N):
        f = F[i]
        j = -(i+1)
        a = A[j]
        b = x // f
        s += max(0,a-b)
    if s <= K:
        u = x
    else:
        d = x
print(u)

Solution (Python):
import sys
sys.setrecursionlimit(10**9)
INF=10**18
def input():
    return sys.stdin.readline().rstrip()

def main():
    N,K=map(int,input().split())
    A=list(map(int,input().split()))
    A.sort()
    F=list(map(int,input().split()))
    F.sort(reverse=True)
    
    def nibutan(ok,ng):
        while abs(ok-ng) > 1:
            mid = (ok + ng) // 2
            if solve(mid):
                ok = mid
            else:
                ng = mid
        return ok
    
    def solve(mid):
        k=0
        for i in range(N):
            k+=max(0,-(-(A[i]*F[i]-mid)//F[i]))
        if k<=K:
            return True
        else:
            return False
    
    print(nibutan(10**18,-1))
        
    
    

if __name__ == '__main__':
    main()

Solution (Python):
def ints():
  return [int(x) for x in input().split()]
def ii():
  return int(input())

import math

N, K = ints()
A = list(sorted(ints()))
F = list(reversed(sorted(ints())))
AF = [A[i]*F[i] for i in range(N)]

afmax = max(AF)

def can(seiseki):
  k = K
  for i in range(N):
    af = AF[i]
    if af>seiseki:
      k -= math.ceil((af-seiseki)/F[i])
      if k<0:
        return False
  return k>=0

l = -1
r = afmax
while r-l>1:
  m = (l+r)//2
  if can(m):
    r = m
  else:
    l = m
print(r)

Solution (Python):
def ints():
  return [int(x) for x in input().split()]
def ii():
  return int(input())

import math

N, K = ints()
A = list(sorted(ints()))
F = list(reversed(sorted(ints())))
AF = [A[i]*F[i] for i in range(N)]

afmax = max(AF)

def can(max_af):
  k = K
  for i in range(N):
    af = AF[i]
    if af>max_af:
      max_ai = max_af // F[i]
      k -= A[i]-max_ai
      if k<0:
        return False
  return k>=0

l = -1
r = afmax
while r-l>1:
  m = (l+r)//2
  if can(m):
    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()))

k = max(sum(a)-k,0)

a.sort()
f.sort()
f.reverse()


l = -1
r = a[-1]*f[0]*2

while l+1!=r:
    x = (l+r)//2
    b = []
    for i in range(n):
        b.append(min(x//f[i], a[i]))
    if k<=sum(b):
        r=x
    else:
        l=x

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)
l=-1
r=10**13
while r-l!=1:
    m=(l+r)//2
    x=0
    for i in range(N):
        x+=max(0,A[i]-m//F[i])
    if x<=K:
        r=m
    else:
        l=m
print(r)

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)
AF=[0]*N

for i in range(N):
    AF[i]=A[i]*F[i]
    
ng=-1
ok=10**12+1


while ok-ng!=1:
    x = (ok+ng)//2
    num_tra =0
    for i in range(N):
        af_i = int(math.ceil((AF[i]-x)/F[i]))
        if af_i>0:
            num_tra+=af_i
    if num_tra<=K:
        ok=x
    else:
        ng=x
        
print(ok)

Solution (Python):
def main():
    import numpy as np
    n, k = map(int, input().split())
    aa = np.array(sorted(list(map(int, input().split()))), dtype=np.int64)
    f = np.array(sorted(list(map(int, input().split())),
                        reverse=True), dtype=np.int64)

    a = 0
    b = 10**12+10
    while a+1 < b:
        med = (a+b)//2
        if np.sum(np.maximum(aa-med//f, np.zeros(n, dtype=np.int64))) > k:
            a = med+1
        else:
            b = med
    if a == b:
        print(a)
    else:
        if np.sum(np.maximum(aa-a//f, np.zeros(n, dtype=np.int64))) > k:
            print(b)
        else:
            print(a)


main()

Solution (Python):
import numpy as np
def solve(n, k, a, f):
    a = sorted(a)
    f = sorted(f)[::-1]
    a = np.asarray(a, dtype=int)
    f = np.asarray(f, dtype=int)
    total = np.sum(a)
    l = -1
    r = np.max(a*f)
    while r - l > 1:
        th = (l + r) // 2
        cost = total - np.minimum(a, th // f).sum()
        if cost <= k:
            r = th
        else:
            l = th
    return r

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

Solution (Python):
import sys
import heapq
sys.setrecursionlimit(10**7)
INTMAX = 9223372036854775807
INTMIN = -9223372036854775808
DVSR = 1000000007
def POW(x, y): return pow(x, y, DVSR)
def INV(x, m=DVSR): return pow(x, m - 2, m)
def DIV(x, y, m=DVSR): return (x * INV(y, m)) % m
def LI(): return [int(x) for x in input().split()]
def LF(): return [float(x) for x in input().split()]
def LS(): return input().split()
def II(): return int(input())
def FLIST(n):
    res = [1]
    for i in range(1, n+1): res.append(res[i-1]*i%DVSR)
    return res

N,K=LI()
As=LI()
As.sort()
Fs=LI()
Fs.sort(reverse=True)

rgt = 10**12
lft = 0
while lft < rgt:
    cost = K
    half = (lft + rgt) // 2
    for i in range(N):
        if As[i]*Fs[i] > half:
            cost -= (As[i]*Fs[i] - half) // Fs[i]
            cost -= 1 if (half - As[i]*Fs[i]) % Fs[i] > 0 else 0

    if cost < 0:
        lft = half + 1
    else:
        rgt = half
    

print(rgt)

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)

def score(x):
    syugyo = 0
    for A,F in zip(a,f):
        sup = x//F
        if sup < A:
            syugyo += A-sup
    if syugyo <= k:
        return True
    return False


left = 0
right = a[-1]*f[0]+1
while left < right-1:
    mid = (left+right)//2
    if score(mid):
        right = mid
    else:
        left = mid
print(left+1 if left != 0 else 0)

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)

def score(x):
    syugyo = 0
    for A,F in zip(a,f):
        syugyo += max(A-int(x/F),0)
    if syugyo <= k:
        return True
    else:
        return False


left = 0
right = a[-1]*f[0]+1
while left < right-1:
    mid = (left+right)//2
    if score(mid):
        right = mid
    else:
        left = mid
print(left+1 if left != 0 else 0)

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

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

Solution (Python):
n,k=map(int,input().split())
a=sorted(list(map(int,input().split())))
b=sorted(list(map(int,input().split())))[::-1]
l,r=10**12+1,-1
while l-r>1:
    t=(l+r)//2
    s=k
    for i,j in zip(a,b):
        if t<i*j:s-=i-t//j
    if s<0:r=t
    else:l=t
print(l)