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):
from numpy import*
(_,k),*t=[int64(t.split())for t in open(0)]
A,F=map(sort,t)
l=-1
r=10**12
while r-l>1:
 m=l+r>>1
 if sum(A-minimum(A,m//F[::-1]))>k:l=m
 else:r=m
print(r)

Solution (Python):
from numpy import*
(_,k),*t=[int64(t.split())for t in open(0)]
A,F=map(sort,t)
l=-1
r=10**12
while r-l>1:
 m=l+r>>1
 if sum(A)-sum(minimum(A,m//F[::-1]))>k:l=m
 else:r=m
print(r)

Solution (Python):
from numpy import*
(_,k),*t=[int64(t.split())for t in open(0)]
A,F=map(sort,t)
s=sum(A)
l=-1
r=10**12
while r-l>1:
 m=l+r>>1
 if s-sum(minimum(A,m//F[::-1]))>k:l=m
 else:r=m
print(r)

Solution (Python):
(_,k),*t=[map(int,t.split())for t in open(0)]
A,F=map(sorted,t)
o=10**12
g=-1
while o-g>1:
 m,l=o+g>>1,k
 for a,f in zip(A,F[::-1]):l-=max(0,a-m//f)
 if l<0:g=m
 else:o=m
print(o)

Solution (Python):
i,s=lambda:map(int,input().split()),sorted
n,k=i()
z=s(i()),s(i())[::-1]
o=10**12
g=-1
while o-g>1:
 m,l=o+g>>1,k
 for a,f in zip(*z):l-=max(0,a-m//f)
 if l<0:g=m
 else:o=m
print(o)

Solution (Python):
n,k,*a=map(int,open(0).read().split())
z=sorted(a[:n]),sorted(a[n:])[::-1]
o=10**12
g=-1
while o-g>1:
 m,l=o+g>>1,k
 for a,f in zip(*z):l-=max(0,a-m//f)
 if l<0:g=m
 else:o=m
print(o)

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)

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

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

Solution (Python):
n,k,*a=map(int,open(0).read().split())
a,f=sorted(a[:n]),sorted(a[n:],reverse=1)
ok=10**12
ng=-1
while ok-ng>1:
    mid=(ok+ng)//2
    l=k
    for b,g in zip(a,f):
        t=b-mid//g
        if t>0:l-=t
    if l<0:ng=mid
    else:ok=mid
print(ok)

Solution (Python):
def main():
    n,k,*a=map(int,open(0).read().split())
    a,f=sorted(a[:n]),sorted(a[n:],reverse=1)
    ok=10**12
    ng=-1
    while ok-ng>1:
        mid=(ok+ng)//2
        l=k
        for b,g in zip(a,f):
            t=b-mid//g
            if t>0:l-=t
        if l<0:ng=mid
        else:ok=mid
    print(ok)
main()

Solution (Python):
def main():
    n,k,*a=map(int,open(0).read().split())
    a,f=sorted(a[:n]),sorted(a[n:],reverse=1)
    ok=10**12
    ng=-1
    while ok-ng>1:
        mid=(ok+ng)//2
        l=k
        for b,g in zip(a,f):
            t=b-mid//g
            if t>0:l-=t
        if l<0:ng=mid
        else:ok=mid
    print(ok)
main()

Solution (Python):
def main():
    n,k,*a=map(int,open(0).read().split())
    a,f=sorted(a[:n]),sorted(a[n:],reverse=1)
    ok=10**12
    ng=-1
    while ok-ng>1:
        mid=(ok+ng)//2
        l=k
        for b,g in zip(a,f):
            if b*g>mid:l-=b-mid//g
        if l<0:ng=mid
        else:ok=mid
    print(ok)
main()

Solution (Python):

import sys
import bisect

def solve(N: int, K: int, A: "List[int]", F: "List[int]"):
    import numpy as np

    A = np.array(A)
    F = np.array(F)

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

    sum_A = A.sum()
    if sum_A <= K:
        ans = 0
    else:
        high = (A * F).max()
        low = 0
        mid = (high + low) // 2
        while low < mid < high:
            if sum_A - np.minimum(A, mid // F).sum() <= K: 
                high = mid
            else:
                low = mid
            mid = (high + low) // 2
        ans = high

    print(ans)

    return


def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  
    K = int(next(tokens))  
    A = [int(next(tokens)) for _ in range(N)]  
    F = [int(next(tokens)) for _ in range(N)]  
    solve(N, K, A, F)

if __name__ == '__main__':
    main()

Solution (Python):
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()
 
    if K >= sum(A): return 0
 
    B = [A[i] * F[i] for i in range(N)]
    l, r = 0, max(B)
    ans = float('inf')
    while l <= r:
        m = (l+r) // 2
        count = 0
        for i in range(N):
            if B[i] - m > 0:
                count += (B[i] - m) // F[i]
                if (B[i] - m) % F[i] != 0:
                    count += 1
        if count <= K:
            ans = min(ans, m)
            if r == m-1: break
            r = m-1
        else:
            if l == m+1: break
            l = m+1
        
    return ans
 
if __name__ == '__main__':
    print(main())

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)

maxaf=a[0]*f[0]
for i in range(n):
	if a[i]*f[i]>maxaf:
		maxaf=a[i]*f[i]

def solve(x):
	total=0
	for i in range(n):
		total+=max(0,a[i]-x//f[i]) 
	return total<=k


ok=maxaf
ng=-1

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

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

A_sort = sorted(A)
F_sort = sorted(F,reverse=True)
A_sort = np.array(A_sort)
F_sort = np.array(F_sort)
Asum = A_sort.sum()

l = -1
r = 0
for i in range(N):
    r = max(r,A_sort[i]*F_sort[i])

def judge(c):
    return Asum - np.minimum(A_sort,c//F_sort).sum() <= K

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

Solution (Python):
import sys
import heapq


def main():
    n, k = [int(s) for s in sys.stdin.readline().strip().split()]
    a = [int(s) for s in sys.stdin.readline().strip().split()]
    f = [int(s) for s in sys.stdin.readline().strip().split()]
    
    
    

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

    def possible(x1):
        improved = 0
        for i in range(n):
            before = a[i] * f[i]
            if before > x1:
                needed_to_be_reduced = before - x1
                if needed_to_be_reduced % f[i] == 0:
                    plus_one = 0
                else:
                    plus_one = 1
                improved += (needed_to_be_reduced // f[i]) + plus_one
                if improved > k:
                    return False
        return True

    def b_search():
        lo = 0
        hi = 10 ** 12
        
        
        

        while lo < hi:
            mid = (lo + hi) // 2
            if possible(mid):
                hi = mid
            else:
                lo = mid+1
        return hi

    ans = b_search()
    print(ans)


main()

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

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

l = -1
r = 0
for i in range(N):
    r = max(r,A_sort[i]*F_sort[i])

def judge(c):
    s = 0
    for i in range(N):
        s += max(A_sort[i]-c//F_sort[i],0)
    return s <= K

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

Solution (Python):
def main():
    n,k=map(int,input().split(' '))
    a=sorted(list(map(int,input().split(' '))),reverse=True)
    f=sorted(list(map(int,input().split(' '))))
    lb=0
    ub = 0
    for i,j in zip(a,f):
        ub = max(ub,i*j)
    def C(x):
        k_tmp = k
        for i,j in zip(a,f):
            k_tmp -= max(0,i-x//j)
            if k_tmp < 0:
                return False
        return True

    while ub-lb>1:
        mid = (lb+ub)/2
        if C(mid):
            ub = mid
        else:
            lb = mid
    if C(lb):
        print(int(lb))
    else:
        print(int(ub))


if __name__ == '__main__':
    main()

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

a = map(int, input().split())
f = map(int, input().split())

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

def judge(n):
    s = 0
    for x, y in zip(a, f):
        s += max(0, x - n // y)
    if s <= k:
        return True
    else:
        return False

low = 0
high = a[-1] * f[0]
while high - low > 0:
    mid = (high + low) // 2
    if judge(mid):
        high = mid
    else:
        low = mid + 1
print(high)

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

import sys
import math

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

def cond(score):
    _max = 0
    count = 0
    for i in range(n):
        if a[i] * f[i] <= score:
            continue
        target = (score // f[i])
        count += a[i] - target
        if count > k:
            return False, -1
        _max = max(_max, target * f[i])
    if count <= k:
        return True, _max

def binary_search(start, end, result):
    middle = math.ceil((start + end) / 2)
    if middle == end:
        if result[start]:
            return start
        else:
            return end
    is_ok, score = cond(middle)
    result[middle] = is_ok
    if is_ok:
        return binary_search(start, min(middle, score), result)
    else:
        return binary_search(middle, end, result)


if sum(a) <= k:
    print(0)
    sys.exit(0)

max_score = 0
for i in range(n):
    max_score = max(max_score, a[i] * f[i])


if k == 0:
    print(max_score)
    sys.exit(0)


if cond(1)[0]:
    print(1)
    sys.exit(0)

result = {1: False, max_score: True}
print(binary_search(1, max_score, result))

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()
li = [0]*n
for i in range(n):
	li[i] = a[i]*f[i]

l=-1
r=10**18+5

while(l+1<r):
	m=(l+r)//2
	cnt=0
	for i in range(n):
		ov = li[i]-m
		if ov>0:
			cnt+= (ov+f[i]-1)//f[i]
	if cnt<=k:
		r=m
	else:
		l=m
print(r)

Solution (Python):
from subprocess import*
call(('pypy3','-c',"""
def main():
    n,k,*a=map(int,open(0).read().split())
    a,f=sorted(a[:n]),sorted(a[n:])[::-1]
    ok=10**12
    ng=-1
    while abs(ok-ng)>1:
        mid=(ok+ng)//2
        l=k
        for b,g in zip(a,f):
            if b*g>mid:
                l-=b-mid//g
                if l<0:
                    ng=mid
                    break
        else:ok=mid
    print(ok)
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))


def test(x):
    cost = np.maximum(0, a-x//f).sum()
    return cost <= k


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

print(right)

Solution (Python):
import sys
from collections import Counter, deque, defaultdict
from math import factorial
from fractions import Fraction
import heapq, bisect
import math
import itertools
sys.setrecursionlimit(10 ** 5 + 10)
INF = 10**15 +5
def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))

n, k = MAP()
a = LIST()
f = LIST()
a = sorted(a, reverse = True)
f = sorted(f)

def ok(x):
    res = 0
    for i in range(n):
        res += max(a[i] - x//f[i], 0)
    return res <= k

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

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.sort()
F[::-1].sort()

sum_A = A.sum()
if sum_A <= K:
    ans = 0
else:
    high = (A * F).max()
    low = 0
    mid = (high + low) // 2
    while low < mid < high:
        if sum_A - np.minimum(A, mid // F).sum() <= K:
            high = mid
        else:
            low = mid
        mid = (high + low) // 2
    ans = high

print(ans)

Solution (Python):
from sys import stdout
import heapq
printn = lambda x: stdout.write(x)
inn = lambda : int(input())
inl   = lambda: list(map(int, input().split()))
inm   = lambda:      map(int, input().split()) 
DBG = True  and False
BIG = 999999999
R = 10**9 + 7

def ddprint(x):
  if DBG:
    print(x)

def foo(t):
  
  cnt = 0
  for j in range(n):
    v,i = b[j]
    
    if v<=t:
      return (cnt<=k)
    d = (v-t+f[i]-1)//f[i]
    cnt += d
    if cnt>k:
      return False
  return (cnt<=k)

n,k = inm()
a = inl()
f = inl()
a.sort()
f.sort(reverse=True)
b = [(f[i]*a[i], i) for i in range(n)]
b.sort(reverse=True)
c = [z[0] for z in b]
mx = max(c)
mn = -1
mid = mx
while mx>mn+1:
  mid = (mx+mn)//2
  if foo(mid):
    
    mx = mid
  else:
    
    mn = mid
print(mx)

Solution (Python):


import numpy as np


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

lower = 0
upper = A[-1] * F[0]


while lower <= upper:
    result = (lower + upper) // 2
    
    
    if np.clip(A - result//F, 0, None).sum() <= K:
        ans = result
        upper = result - 1
    else:
        lower = result + 1

print(ans)

Solution (Python):


import numpy as np


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

lower = 0
upper = A[-1] * F[0]


while lower <= upper:
    result = (lower + upper) // 2
    
    
    if np.clip(A - result//F, 0, None).sum() <= K:
        ans = result
        upper = result - 1
    else:
        lower = result + 1

print(ans)

Solution (Python):
import math

N, K = map(int, input().split())

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

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

def check(x):
  k = K
  for i in range(N):
    k -= max(0,math.ceil((A[i]*F[i]-x)/F[i]))

  return k >= 0



left = 0
right = 10**12

if check(left):
  print(0)
  exit()

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


print(right)

Solution (Python):
inpl = lambda: list(map(int,input().split()))
def bisect_left_withkey(a, x, lo=0, hi=None, key=lambda x: x, keyvalue_x=False):
    left = lo
    right = len(a) if hi is None else hi
    kx = key(x) if keyvalue_x else x
    while left + 1 < right:
        new = (left + right)//2
        kn = key(a[new])
        if kx <= kn:
            right = new
        else:
            left = new
    if key(a[left]) == kx:
        return left
    else:
        return right

N, K = inpl()
A = inpl()
F = inpl()
A.sort(reverse=True)
F.sort()
score = [A[i]*F[i] for i in range(N)]

def achievable(m):
    k = 0
    for i in range(N):
        k += max(0, (score[i]-m-1)//F[i] + 1)
        if k > K:
            return False
    return True

M = max(score)
print(bisect_left_withkey(range(M+1), True, key=achievable))

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=1)
su=ok=ng=0
for i in range(n):
  ok=max(ok,a[i]*f[i])
  su+=a[i]
if su<=k:print(0);exit()
while ng+1<ok:
  mid=(ok+ng)//2
  h=0
  for i in range(n):
    r=a[i]-(mid//f[i])
    if (r<0):
      r=0
    h+=r
  if h<=k:ok=mid
  else:ng=mid
print(ok)

Solution (Python):
N,K = map(int, input().strip().split(' '))
A = sorted(list(map(int, input().strip().split(' '))), reverse=True)
F = sorted(list(map(int, input().strip().split(' '))))
if sum(A) <= K:
  print(0)
  exit()

ng = 0
ok = max([a*f for a,f in zip(A,F)])
while True:
  if ok-ng == 1: break
  m = int((ng+ok)/2)
  now_cost = 0
  for a,f in zip(A,F):
    now_cost += max(a-(m//f), 0)
  if now_cost <= K:
    ok = m
  else:
    ng = m
    
print(ok)

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

lower = 0
upper = A[-1] * F[0]


while lower <= upper:
    result = (lower + upper) // 2
    
    
    if np.clip(A - result//F, 0, None).sum() <= K:
        ans = result
        upper = result - 1
    else:
        lower = result + 1

print(ans)

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

def check(A, F, mid, k):
    for i in range(len(A)):
        if A[i] * F[i] > mid:
            x = A[i] - mid // F[i]
            k -= x
        if k < 0:
            return False
    return True



def main():
    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_s = sorted(A, reverse=True)
    F_s = sorted(F)

    l = -1
    r = 10 ** 13
    while r - l != 1:
        mid = (r + l) // 2
        if check(A_s, F_s, mid, K):
            r = mid
        else:
            l = mid

    print(r)











if __name__ == '__main__':
    main()

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=1)
su=ok=ng=0
for i in range(n):
  ok=max(ok,a[i]*f[i])
  su+=a[i]
if su<=k:print(0);exit()
while ng+1<ok:
  mid=(ok+ng)//2
  h=0
  for i in range(n):
    h+=max(a[i]-(mid//f[i]),0)
  if h<=k:ok=mid
  else:ng=mid
print(ok)

Solution (Python):
from numpy import array, int64, minimum

def main():
    N, K, *I = open(0).read().split()
    N, K = map(int, (N, K))

    A, F = array(I[:N], int64), array(I[N:], int64)
    A.sort()
    F.sort()
    F = F[::-1]

    sum_A = A.sum()

    ng, ok = -1, 10 ** 12
    while ng + 1 < ok:
        mid = (ok + ng) // 2
        if (sum_A - minimum(A, mid // F).sum()) <= K:
            ok = mid
        else:
            ng = mid

    print(ok)


if __name__ == '__main__':
    main()

Solution (Python):
N, K  = map(int, input().split())
As = sorted(list(map(int, input().split())))
Fs = sorted(list(map(int, input().split())),reverse=True)
Xs = [a*f for a,f in zip(As,Fs)]
X_M = max(Xs)

def f(x):
    K_tmp = sum([max(0,a-x//f) for a,f in zip(As,Fs)])
    return K_tmp <= K

def  binarySearch(l,r,target):
    while r - l > 1:
        mid = (l+r)//2
        """計算を入れる"""
        
        if f(mid):
            r = mid
        else:
            l = mid
    return r

print(binarySearch(-1,X_M,K))

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)

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

ok = max(A)*max(F)
ng = -1 

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

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]
sumA = A.sum()

def can_eat(x):
  
  
  
  
  
  
  
  
  
  
  eat_cost_for_x = np.minimum(A, x // F)
  
  
  
  
  return sumA - eat_cost_for_x.sum() <= K



left = -1 

right = 10**12



while left + 1 < right:
  mid = (left+right)//2
  
  
  if can_eat(mid):
    right = mid
  
  else:
    left = mid
 
answer = right
print(answer)

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]
a_sum = a.sum()
low, high = -1, max(a)*max(f)
while low + 1 < high:
  mid = (low + high) // 2
  if np.minimum(a, mid // f).sum() >= a_sum - k:
    high = mid
  else:
    low = mid
print(high)

Solution (Python):
from numpy import array, int64, minimum
from sys import stdin

def main():
    input = stdin.buffer.readline

    N, K = map(int, input().split())

    A, F = array(input().split(), int64), array(input().split(), int64)
    A.sort()
    F.sort()
    F = F[::-1]

    sum_A = A.sum()

    ng, ok = -1, 10 ** 12
    while ng + 1 < ok:
        mid = (ok + ng) // 2
        if (sum_A - minimum(A, mid // F).sum()) <= K:
            ok = mid
        else:
            ng = mid

    print(ok)


if __name__ == '__main__':
    main()

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)

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

ok = max(A)*max(F)
ng = 0

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

Solution (Python):
from numpy import array, int64, minimum

def main():
    N, K, *I = map(int, open(0).read().split())

    A, F = array(I[:N], int64), array(I[N:], int64)
    A.sort()
    F.sort()
    F = F[::-1]

    sum_A = A.sum()

    ng, ok = -1, 10 ** 12
    while ng + 1 < ok:
        mid = (ok + ng) // 2
        if (sum_A - minimum(A, mid // F).sum()) <= K:
            ok = mid
        else:
            ng = mid

    print(ok)


if __name__ == '__main__':
    main()

Solution (Python):
import numpy as np

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

a = np.sort(a)
f = np.sort(f)[::-1]


def ok(x):
    return np.clip(a - x // f, 0, None).sum() <= k


l, r = 0, 10 ** 12

while l <= r:
    mid = (l + r) // 2
    if ok(mid):
        r = mid - 1
    else:
        l = mid + 1

print(l)

Solution (Python):
import numpy as np

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

Asum = sum(A)

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

def test(x):
    res = np.maximum(0,Asort-x//Fsort).sum()
    return res <= K

left = -1
right = 10**13

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

ans = right

print(ans)

Solution (Python):
import math
(n,k),a,f = [list(map(int, s.split())) for s in open(0)]

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

low = 0
high = 0
for x, y in zip(a,f):
    high = max(high, x*y)

while high != low:
    test = int((high + low) // 2)
    tmp = 0
    for x, y in zip(a,f):
        tmp += max(0, x - math.floor(test / y))
        if tmp > k:
            low = test + 1
            break
    else:
        high = test
print(high)

Solution (Python):
import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, radians, atan, degrees
from itertools import permutations, combinations, product, accumulate
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from fractions import gcd
from bisect import bisect
import heapq
import numpy as np

def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7

def main():
	N, K = MAP()
	A = LIST()
	F = LIST()

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

	A = np.array(A)
	F = np.array(F)
	time = A*F
	
	
	sum_A = A.sum()

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

	min_ = -1
	max_ = 10**18
	while min_ + 1 != max_:
		search = (min_+max_)//2
		
		if is_ok(search):
			max_ = search
		else:
			min_ = search

	print(max_)


if __name__ == "__main__":
	main()

Solution (Python):
(n,k),a,f = [list(map(int, s.split())) for s in open(0)]

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

low = 0
high = 0
for x, y in zip(a,f):
    high = max(high, x*y)

while high != low:
    test = int((high + low) // 2)
    tmp = 0
    for x, y in zip(a,f):
        tmp += max(0, x - int(test / y))
        if tmp > k:
            low = test + 1
            break
    else:
        high = test
print(high)

Solution (Python):
N,K = map(int,input().split())
A = list(map(int,input().split()))
F = list(map(int,input().split()))
import numpy as np
s_A = sum(A)
if s_A<=K:
  print(0)

else:
  A.sort()
  F.sort(reverse=True)
  A = np.array(A)
  F = np.array(F)
  mi=0
  ma=max(F)*max(A)
  while mi+1<ma:
    mid = (mi+ma)//2
    if s_A-np.minimum(A,mid//F).sum()<=K:
      ma=mid
    else:
      mi=mid

  print(ma)

Solution (Python):
inpl = lambda: list(map(int,input().split()))
def bisect_left_withkey(a, x, lo=0, hi=None, key=lambda x: x, keyvalue_x=False):
    left = lo
    right = len(a) if hi is None else hi
    kx = key(x) if keyvalue_x else x
    while left + 1 < right:
        new = (left + right)//2
        kn = key(a[new])
        if kx <= kn:
            right = new
        else:
            left = new
    if key(a[left]) == kx:
        return left
    else:
        return right

N, K = inpl()
A = inpl()
F = inpl()
A.sort()
F.sort(reverse=True)
score = [A[i]*F[i] for i in range(N)]

def achievable(m):
    k = 0
    for i in range(N):
        k += max(0, (score[i]-m-1)//F[i] + 1)
        if k > K:
            return False
    return True

M = max(score)
print(bisect_left_withkey(range(M+1), True, key=achievable))

Solution (Python):
import sys


def solve():
    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)
    left = -1
    right = 10 ** 13
    while right - left > 1:
        mid = (left + right) // 2
        count = 0
        for av, fv in zip(a, f):
            count += max(0, av - (mid // fv))
        if count <= k:
            right = mid
        else:
            left = mid
    print(right)


if __name__ == '__main__':
    solve()

Solution (Python):
def main():
    N, K, *I = map(int, open(0).read().split())
    A, F = I[:N], I[N:]

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

    ng, ok = -1, 10 ** 12
    while abs(ok - ng) > 1:
        mid = (ok + ng) // 2
        if sum(max(0, a - mid // f) for a, f in zip(A, F)) <= K:
            ok = mid
        else:
            ng = mid

    print(ok)


if __name__ == '__main__':
    main()

Solution (Python):
N, K = map(int, input().split())
A = sorted(list(map(int, input().split())))
F = sorted(list(map(int, input().split())), reverse=True)
 
def isEaten(x):
    temp = 0
    for i in range(N):
        t = x // F[i]
        if t < A[i]:
            temp += (A[i] - t)
    return temp <= K
 
 
def bitSearch(r, l):
    m = (r+l) // 2
    if m == l:
        if isEaten(l):
            print(l)
        else:
            print(r)
        exit()
    elif isEaten(m):
        bitSearch(m, l)
    else:
        bitSearch(r, m)
 
 
target = max([A[i]*F[i] for i in range(N)])
bitSearch(target, 0)

Solution (Python):
n,k=map(int,input().split())
a=[int(j) for j in input().split()]
f=[int(j) for j in input().split()]
a.sort()
f.sort()
f.reverse()
if k>=sum(a):
    print(0)
    exit()

ans=[]
a.sort()
for i in range(n):
    ans.append([a[i]*f[i],a[i]])
ans.sort()
ans.reverse()

def fun(m):
    p=0
    for i,j in zip(a,f):
        if i>m//j:
            p+=i-(m//j)
            if p>k:
                return False
    return True

left=0
right=ans[0][0]
while right-left>1:
    mid=(left+right)//2
    if fun(mid):
        right=mid   
    else:
        left=mid

print(right)

Solution (Python):
import math
(n,k),a,f = [list(map(int, s.split())) for s in open(0)]

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

low = 0
high = 0
for x, y in zip(a,f):
    high = max(high, x*y)

while high != low:
    test = int((high + low) // 2)
    tmp = 0
    for x, y in zip(a,f):
        tmp += max(0, x - math.floor(test / y))
        if tmp > k:
            low = test + 1
            break
    else:
        high = test
print(high)

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 = a[-1]*f[0], -1
while ok-ng > 1:
	x = (ok+ng)//2
	tmp = 0
	for i in range(n):
		tmp += max(0, a[i] - x//f[i])
	if tmp > k:
		ng = x
	else:
		ok = x
print(ok)

Solution (Python):
def main():
    n,k,*a=map(int,open(0).read().split())
    a,f=sorted(a[:n])[::-1],sorted(a[n:])
    ok=10**12
    ng=-1
    while abs(ok-ng)>1:
        mid=(ok+ng)//2
        l=k
        for b,g in zip(a,f):
            if b*g>mid:
                l-=b-mid//g
        if l<0:ng=mid
        else:ok=mid
    print(ok)
main()

Solution (Python):
import numpy as np

n, k = map(int, input().split())
a = np.sort(np.array(input().split(), dtype=np.int))
f = np.sort(np.array(input().split(), dtype=np.int))
time = f * a[::-1]

sup = time.max()
inf = 0
while sup > inf:
  x = (sup + inf) // 2
  train = ((np.maximum(time - x, 0) + f - 1) // f).sum()
  if k < train:
    inf = x + 1
  else:
    sup = x
print(sup)

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

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

ma = 2**40
mi = 0
while 1:
    tgt = mi + (ma - mi)//2
    num = 0
    for i in range(N):
        tmp = (mul[i] - tgt + F[i] - 1) // F[i]
        if tmp <= 0:
            continue
        num += tmp
    if ma == mi:
        print(ma)
        exit()
    if num <= K:
        ma = mi + (ma - mi)//2
    else:
        mi = mi + (ma - mi)//2+1