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

q = [0] * N
start = -1
end = 0
for i in range(N):
    q[i] = A[i] * F[i]
    end = max(end, q[i])

def check(now, K):
    cnt = 0
    for i in range(N):
        if q[i] - now > 0:
            cnt += (q[i] - now + F[i] - 1) // F[i]
            if cnt > K:
                return False
    return True

now = end // 2
while end > start + 1:
    if check(now, K):
        end = now
    else:
        start = now
    now = (start + end) // 2

print(end)

Solution (Python):
import sys
sys.setrecursionlimit(10000000)
def input():
    return sys.stdin.readline()[:-1]

from collections import *
from heapq import *

import math



N, K = map(int, input().split())
A = [int(x) for x in input().split()]
A.sort()
F = [int(x) for x in input().split()]
F.sort(reverse = 1)
l, r = -1, 10**12
while l+1 < r:
    x = (l+r)//2
    c = 0
    for a, f in zip(A, F):
        if a*f > x:
            c += max(0,a-x//f)
    if c > K:
        l = x
    else:
        r = x
print(r)

Solution (Python):
def p(F,A,s): 
    res=0
    for i in range(N):
        res+=max(A[i]-s//F[i],0)
    return res

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

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

l=0
r=max([F[i]*A[i] for i in range(N)])

while r-l>1:
    m=(l+r)//2
    if p(F,A,m)<=K:
        r=m
    else:
        l=m

print(r if p(F,A,0)>K else 0)

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)

q = [0] * N
start = 0
end = 0
for i in range(N):
    q[i] = A[i] * F[i]
    end = max(end, q[i])

def check(now, K):
    cnt = 0
    for i in range(N):
        if q[i] - now > 0:
            cnt += (q[i] - now + F[i] - 1) // F[i]
            if cnt > K:
                return False
    return True

now = end // 2
while end > start + 1:
    if check(now, K):
        end = now
    else:
        start = now
    now = (start + end) // 2

if check(start, K):
    print(start)
else:
    print(end)

Solution (Python):
def p(F,A,s): 
    res=0
    for i in range(N):
        res+=max(A[i]-s//F[i],0)
    return res

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

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

l=0
r=max([F[i]*A[i] for i in range(N)])

while r-l>1:
    m=(l+r)//2
    if p(F,A,m)<=K:
        r=m
    else:
        l=m

if r>1 or p(F,A,0)>K:
    ans=r
else:
    ans=0

print(ans)

Solution (Python):
def e_gluttony():
    
    import sys
    import numpy as np
    input = sys.stdin.readline
    N, K = [int(i) for i in input().split()]
    A = np.array(sorted([int(i) for i in input().split()]))
    F = np.array(sorted([int(i) for i in input().split()], reverse=True))

    if A.sum() <= K:
        return 0  

    def can_eat(x):
        """全員が x 秒以下で食べるために必要な修行回数は K 以下か？"""
        t = A - (x // F)  
        return t[t > 0].sum() <= K

    
    cannot_eat, lower_bound = -1, 10**12 + 1
    while lower_bound - cannot_eat > 1:
        mid = (cannot_eat + lower_bound) // 2
        if can_eat(mid):
            lower_bound = mid
        else:
            cannot_eat = mid
    return lower_bound

print(e_gluttony())

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, r = -1, 10 ** 12


def func(x):  
    k = 0  
    for a, f in zip(A, F):  
        e = x // f
        if a <= e:  
            continue
        k += a - e
        
    if k <= K:
        return 1
    return 0


while (r - l > 1):  
    mid = (l + r) // 2
    if func(mid):
        r = mid
    else:
        l = mid


print(r)

Solution (Python):
import sys
import heapq


def can_eat_with_score(key):
    now_K = K
    for i, now_score in enumerate(score):
        if key < now_score:
            now_K -= (now_score-key+F[i]-1) // F[i]
            if now_K < 0:
                return False
    return True


input = sys.stdin.readline

priority_que = []
N, K = map(int, input().split())
A = sorted(map(int, input().strip().split()))
F = sorted(map(int, input().strip().split()))[::-1]
score = [A[i]*F[i] for i in range(N)]
if sum(A) <= K:
    print("0")
    exit()


left = -1
right = max(score)
while right - left > 1:
    mid = (left+right) // 2
    can_eat = can_eat_with_score(mid)
    
    if can_eat:
        right = mid
    else:
        left = mid
print(left+1)

Solution (Python):
import sys
def I(): return int(sys.stdin.readline())
def LI(): return list(map(int,sys.stdin.readline().split()))
mod = 10**9 + 7
inf = float('inf')
ans = int(0)
N, K =LI()
A = LI()
F = LI()
A.sort(reverse=True)
F.sort()

xupper = max(A)*max(F)
xlower = int(0)
xcandi = xupper//2

sumA = sum(A)

while (True):

    k = int(0)
    for i in range(N):
        k += max((A[i]*F[i]-xcandi+(F[i]-1))//F[i],0)


    if k>K:
        xlower = xcandi
        xcandi = ((xcandi + xupper) // 2)+1
    else:
        if xupper-xlower<=1:
            ans = xcandi
            break
        else:
            xupper = xcandi
            xcandi = (xcandi + xlower) // 2

print(ans)

Solution (Python):
def check(n, k , a, f, x):
    training_cnt = 0
    for i in range(n):
        t = x // f[i]  
        d = a[i] - t
        if d > 0:
            training_cnt += d
        if training_cnt > k:
            return False
    else:
        return True

def main():
    N, K = map(int, input().split())
    A = sorted([int(i) for i in input().split()])
    F = sorted([int(i) for i in input().split()], reverse=True)

    if check(N, K, A, F, 0):
        print(0)
        return


    left = 0
    right = 10 ** 12

    while left + 1 < right:
        mid = (left + right) // 2
        if check(N, K, A, F, mid):
            right = mid
        else:
            left = mid

    print(right)

if __name__ == '__main__':
    main()

Solution (Python):
n,k=map(int,input().split())
a=list(map(int,input().split()))
f=list(map(int,input().split()))
f.sort()
a.sort()
a.reverse()
l=0
r=10**12+1
import math
while r-l>1:
	mid=(l+r)/2
	cnt=0
	for i in range(n):
		if a[i]*f[i]>mid:
			cnt+=a[i]-mid//f[i]
	if cnt<=k:
		r=mid
	else:
		l=mid
print(int(r))

Solution (Python):



import math
import sys

n,k = map(int,input().split())
al = list(map(int,input().split()))
fl = list(map(int,input().split()))

al.sort()
fl.sort(reverse=True)

ub = max([a*f for a,f in zip(al, fl)])
lb = 0

while True:
    if ub == lb:
        print(lb)
        sys.exit()
    p = 0
    t = (ub + lb) // 2
    for a, f in zip(al, fl):
        p += max(a - t // f, 0)
    if p <= k:
        ub = t
    else:
        lb = t + 1

Solution (Python):
import sys
MAX_INT = int(10e15)
MIN_INT = -MAX_INT
mod = 1000000007
sys.setrecursionlimit(1000000)
def IL(): return list(map(int,input().split()))
def SL(): return input().split()
def I(): return int(sys.stdin.readline())
def S(): return input()

def judge(x):
  cnt = 0
  for i in range(N):
    tmp = a[i] - x//f[i]
    cnt += max(tmp, 0)
  else:
    if cnt <= K:
      return True
    else:
      return False


def nibutan(): 
    left = -1
    ans = num
    while left+1 != ans:
        middle = (left+ans)//2
        if judge(middle):
            ans = middle
        else:
            left = middle
    return ans

N, K = IL()
a = IL()
f = IL()
a.sort()
f.sort(reverse=True)
num = 0
for i in range(N):
  num = max(num, a[i]*f[i])

print(nibutan())

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 = 0
r = max(a) * max(f)

def check(x):
    tot = 0
    for i in range(n):
        need = a[i] - x // f[i]
        tot += need if need >= 0 else 0
    return tot <= k


while l < r:
    m = (l + r) // 2
    if check(m):
        r = m
    else:
        l = m+1

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 isOk(x):
	cost = 0
	for a, f in zip(A,F):
		eatable = x//f
		if eatable >= a:
			continue
		cost += a - eatable
	if cost <= k:
		return True
	return False
left = -1
right = A[-1] * F[0]
while left+1 < right:
	
	mid = (left+right)//2
	if isOk(mid):
		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)
def isOk(x):
	cost = 0
	for a, f in zip(A,F):
		eatable = x//f
		if eatable >= a:
			continue
		cost += a - eatable
	if cost <= k:
		return True
	return False
left = -1
right = A[-1] * F[0]
while left+1 < right:
	
	mid = (left+right)//2
	if isOk(mid):
		right = mid
	else:
		left = mid
print(right)

Solution (Python):
import numpy as np
i8 = np.int64
i4 = np.int32


def solve(A, F, K):
    min_ = 0
    max_ = 10 ** 12
    while min_ < max_:
        mid = (min_ + max_) // 2
        count = A - mid // F
        sum_ = count[count > 0].sum()
        if sum_ <= K:
            max_ = mid
        else:
            min_ = mid + 1
    return min_

def main():
    stdin = open('/dev/stdin', 'rb')
    pin = np.fromstring(stdin.read(), i8, sep=' ')
    N, K = pin[:2]
    A = pin[2: N + 2]
    F = pin[N + 2: 2 * N + 2]
    A = np.sort(A)[::-1]
    F.sort()
    ans = solve(A, F, K)
    print(ans)

if __name__ == '__main__':
    main()

Solution (Python):
from numpy import*
import sys

 
def main():
    n,k=map(int,input().split())
    a=array(sorted(map(int,input().split())))
    b=array(sorted(map(int,input().split())))[::-1]
    ok=max(a)*max(b)
    ng=-1
    s=sum(a)
    def check(a,b,mid,k):
        if s-sum(minimum(a,mid//b))<=k:
            return 1
        else:
            return 0
            
    while abs(ok-ng)>1:
        mid=(ok+ng)//2
        if check(a,b,mid,k):
            ok=mid
        else:
            ng=mid
    print(ok)

if __name__ == '__main__':
    main()

Solution (Python):
import sys
import numpy as np
n, k = [int(i) for i in sys.stdin.readline().split()]
a_ls = [int(i) for i in sys.stdin.readline().split()]
f_ls = [int(i) for i in sys.stdin.readline().split()]
a_ls.sort(reverse=True)
f_ls.sort()
a_sum = sum(a_ls)
a_ls = np.array(a_ls)
f_ls = np.array(f_ls)
minimum = 0
maximum = (a_ls * f_ls).sum()
def check(x):
    """
    :param x:
    :return: x以下で可能か
    """
    return a_sum - np.minimum(a_ls, x // f_ls).sum() <= k
while True:
    center = (maximum + minimum) // 2
    if check(center):
        if maximum == center:
            res = center
            break
        maximum = center
    else:
        if minimum == center:
            if check(maximum):
                res = maximum
                break
            else:
                res = minimum
        minimum = center
print(res)

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 isOk(x):
    cost = 0
    for a, f in zip(A,F):
        eatable = x//f
        if eatable >= a:
            continue
        cost += a - eatable
    if cost <= k:
        return True
    return False

left = -1
right = A[-1] * F[0]
while left+1 < right:
    
    mid = (left+right)//2
    if isOk(mid):
        right = mid
    else:
        left = mid
print(right)

Solution (Python):
import sys
input = sys.stdin.readline
import math
def solve():
  n,k = (int(i) for i in input().split())
  a = sorted(list(int(i) for i in input().split()))
  f = sorted(list(int(i) for i in input().split()),reverse = True)
  if sum(a) <= k:
    print(0)
    exit()
  
  ng = 0
  ok = 10**12

  while ok-ng >1 :
    next = (ok+ng)//2
    
    tmpk = k
    for i in range(n):
      ta = a[i]
      tf = f[i]
      if ta*tf > next:
        tmpk -= math.ceil((ta*tf-next)/tf)

    if tmpk < 0:
       ng = next
    else:
       ok = next
  print(ok)
    
solve()

Solution (Python):
import sys
input = sys.stdin.readline
import math
def solve():
  n,k = (int(i) for i in input().split())
  a = sorted(list(int(i) for i in input().split()))
  f = sorted(list(int(i) for i in input().split()),reverse = True)
  if sum(a) <= k:
    print(0)
    exit()
  
  ng = 0
  ok = 10**15

  while ok-ng >1 :
    next = (ok+ng)//2
    
    tmpk = k
    for i in range(n):
      ta = a[i]
      tf = f[i]
      if ta*tf > next:
        tmpk -= math.ceil((ta*tf-next)/tf)
    if tmpk < 0:
       ng = next
    else:
       ok = next
  print(ok)
    
solve()

Solution (Python):
def check(res,a,f,k):
    for sa,sf in zip(a,f):
        if sa*sf <= res:
            continue
        k -= sa - (res // sf)
        if k < 0:
            return False
    return True


def nibun(l,r,a,f,k):
    if r == l:
        return l
    flag = (l+r)//2
    if check(flag,a,f,k):
        return nibun(l,flag,a,f,k)
    else:
        return nibun(flag+1,r,a,f,k)

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)

    return nibun(0,10**13,a,f,k)


print(main())

Solution (Python):
from copy import deepcopy
from sys import exit,setrecursionlimit
import math
from collections import defaultdict,Counter,deque
from fractions import Fraction as frac
import bisect
import sys
import logging
import heapq



input = sys.stdin.readline

setrecursionlimit(1000000)


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

	right = 10**12
	left = -1

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

def factorization(n):
	arr = []
	temp = n
	for i in range(2, int(-(-n**0.5//1))+1):
		if temp%i==0:
			cnt=0
			while temp%i==0:
				cnt+=1
				temp //= i
			arr.append([i, cnt])

	if temp!=1:
		arr.append([temp, 1])

	if arr==[]:
		arr.append([n, 1])

	return arr

def zip(a):
	mae = a[0]
	ziparray = [mae]
	for i in range(1,len(a)):
		if(mae != a[i]):
			ziparray.append(a[i])
			mae = a[i]
	return ziparray

def is_prime(n):
	if n < 2: return False

	for k in range(2, int(math.sqrt(n)) + 1):
		if n % k == 0:
			return False

	return True

def list_replace(n,f,t):
	return [t if i==f else i for i in n]

def base_10_to_n(X, n):
	X_dumy = X
	out = ''
	while X_dumy>0:
		out = str(X_dumy%n)+out
		X_dumy = int(X_dumy/n)
	if(out == ''): return '0'
	return out

def gcd(l):
	x = l.pop()
	y = l.pop()
	while(x%y!=0):
		z = x%y
		x = y
		y = z
	l.append(min(x,y))
	return gcd(l) if len(l) > 1 else l[0]

class Queue():
	def __init__(self):
		self.q = deque([])
	def push(self,i):
		self.q.append(i)
	def pop(self):
		return self.q.popleft()
	def size(self):
		return len(self.q)
	def debug(self):
		return self.q

class Stack():
	def __init__(self):
		self.q = []
	def push(self,i):
		self.q.append(i)
	def pop(self):
		return self.q.pop()
	def size(self):
		return len(self.q)
	def debug(self):
		return self.q

class graph():
	def __init__(self):
		self.graph = defaultdict(list)
	def addnode(self,l):
		f,t = l[0],l[1]
		self.graph[f].append(t)
		self.graph[t].append(f)
	def rmnode(self,l):
		f,t = l[0],l[1]
		self.graph[f].remove(t)
		self.graph[t].remove(f)
	def linked(self,f):
		return self.graph[f]

class dgraph():
	def __init__(self):
		self.graph = defaultdict(set)
	def addnode(self,l):
		f,t = l[0],l[1]
		self.graph[f].append(t)
	def rmnode(self,l):
		f,t = l[0],l[1]
		self.graph[f].remove(t)
	def linked(self,f):
		return self.graph[f]

class PriorityQueue():
	def __init__(self):
		self.queue = []
	def push(self,i):
		heapq.heappush(self.queue,-i)
	def pop(self):
		return -1 * heapq.heappop(self.queue)
	def sum(self):
		return -sum(self.queue)

main()

Solution (Python):
import numpy as np
i8 = np.int64
i4 = np.int32


def solve(A, F, K):
    min_ = 0
    max_ = 10 ** 12
    while min_ < max_:
        mid = (min_ + max_) // 2
        count = A - mid // F
        sum_ = count[count > 0].sum()
        if sum_ <= K:
            max_ = mid
        else:
            min_ = mid + 1
    return min_

def main():
    stdin = open('/dev/stdin', 'rb')
    pin = np.fromstring(stdin.read(), i8, sep=' ')
    N, K = pin[:2]
    A = pin[2: N + 2]
    F = pin[N + 2: 2 * N + 2]
    A = np.sort(A)[::-1]
    F.sort()
    ans = solve(A, F, K)
    print(ans)

if __name__ == '__main__':
    main()

Solution (Python):

import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

import numpy as np

N,K = map(int,readline().split())
A = np.array(readline().split(),np.int64)
F = np.array(readline().split(),np.int64)

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

Asum = A.sum()

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

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

answer = right
print(answer)

Solution (Python):

n,k=map(int,input().split())
a=list(map(int,input().split()))
a.sort()
f=list(map(int,input().split()))
f.sort(reverse=True)
x=1
i=0
while i>=0:
    cnt=0
    for j in range(n):
        cnt+=max(0,a[j]-x//f[j])
    if cnt>k:
        i+=1
        x=2**i
    else:
        break
while i>0:
    cnt=0
    for j in range(n):
        cnt+=max(0,a[j]-x//f[j])
    if cnt>k:
        i-=1
        x+=2**i
    else:
        i-=1
        x-=2**i
y=x-1
cnt=0
for j in range(n):
    cnt+=max(0,a[j]-y//f[j])
if cnt<=k:
    print(y)
else:
    cnt=0
    for j in range(n):
        cnt+=max(0,a[j]-x//f[j])
    if cnt<=k:
        print(x)
    else:
        print(x+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))

def check(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 check(mid):
        right = mid
    else:
        left = mid
    
print(right)

Solution (Python):
import sys
input = sys.stdin.readline
from operator import itemgetter
sys.setrecursionlimit(10000000)

a = []
f = []
n = 0

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

def main():
    global a, f, n
    n, k = map(int, input().strip().split())
    a = list(map(int, input().strip().split()))
    f = list(map(int, input().strip().split()))
    a = sorted(a)
    f = sorted(f, reverse=True)
    print(rec(-1, 10**12, k))

if __name__ == '__main__':
    main()

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

def check(x):
  cost = np.maximum(0,a-x//f).sum()
  return cost <= k
  
left = -1
right = 10**12
while right - left > 1:
  mid = (right + left) // 2
  if check(mid):
    right = mid
  else:
    left = mid

print(right)

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

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

a_sort = np.array(sorted(a))
f_sort = np.array(sorted(f, reverse=True))

def check(x):
    cost = np.maximum(0, a_sort-x//f_sort).sum()
    return cost <= k

left = -1
right = 10**12

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

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

import numpy as np

N,K = map(int,readline().split())
A = np.array(readline().split(),np.int64)
F = np.array(readline().split(),np.int64)

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

answer = right
print(answer)

Solution (Python):
import sys
input = sys.stdin.readline
from operator import itemgetter
sys.setrecursionlimit(10000000)

a = []
f = []
n = 0

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

def main():
    global a, f, n
    n, k = map(int, input().strip().split())
    a = list(map(int, input().strip().split()))
    f = list(map(int, input().strip().split()))
    a = sorted(a)
    f = sorted(f, reverse=True)
    print(rec(-1, 10**12, k))

if __name__ == '__main__':
    main()

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 = x if keyvalue_x else key(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, keyvalue_x=True))

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)
r = 1e12+1
l = -1
def ok(c):
  s = 0
  for i in range(N):
    s += max(0,A[i]-c//F[i])
  return bool(s<=K)

while l+1 < r:
  c = (l+r) // 2 
  a = ok(c)
  if a == True:
    r = c
  else:
    l = c
print(int(r))

Solution (Python):


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

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

def binary_search(min_f, max_f):
	if min_f == max_f:
		return min_f

	mid_f = min_f + (max_f - min_f)//2
	tmp = 0
	for i in range(N):
		tmp += max(0,A[i] - mid_f // F[i])
	
	if tmp <= K:
		return binary_search(min_f, mid_f)
	else:
		return binary_search(mid_f+1, max_f)

print(binary_search(0, max_f))

Solution (Python):
import sys
sys.setrecursionlimit(10 ** 7)

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)

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

    l = -1
    r = 10 ** 13

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

    while l + 1 < r:
        m = (l + r) // 2
        if test(m):
            r = m
        else:
            l = m

    ans = r
    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):
import sys
sys.setrecursionlimit(10 ** 7)


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)

    l = -1
    r = 10 ** 13

    def test(x):
        cnt = 0
        for ae, fe in zip(a, f):
            cnt += max(0, ae - x // fe)

        return cnt <= k

    while l + 1 < r:
        m = (l + r) // 2
        if test(m):
            r = m
        else:
            l = m

    ans = r
    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):

import sys
INF = float("inf")
import numpy as np


def solve(N: int, K: int, A: "List[int]", F: "List[int]"):
    A.sort()
    F.sort(reverse=True)
    A = np.asarray(A, dtype=np.int)
    F = np.asarray(F, dtype=np.int)

    Asum = A.sum()

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

    def binary_search(x):
        ng = -1
        ok = len(x)
        while abs(ok - ng) > 1:
            mid = (ok + ng)//2
            
            if isOK(mid):
                ok = mid
            else:
                ng = mid
        return ng, ok

    ng, ok = binary_search(range(A.max()*F.max()))
    print(ok)

    
    
    
    
    
    
    
    
    
    
    
    

    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):
import math
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)
l=-1
r=2*10**12+1
while l+1<r:
  c=(l+r)//2
  s=0
  for i in range(n):
    m=max(0,math.ceil((a[i]*f[i]-c)/f[i]))
    s=s+m
  if s>k:
  	l=c
  else:
    r=c
print(r)

Solution (Python):
import sys
from heapq import heappop, heappush
from operator import itemgetter
from collections import deque, defaultdict, Counter
from bisect import bisect_left, bisect_right
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 7)
MOD = 10**9 + 7
INF = float('inf')

def sol():
    _, K = map(int, input().split())
    A = list(map(int, input().split()))
    F = list(map(int, input().split()))

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

    def isOk(t):
        cnt = 0
        for a, f in zip(A, F):
            ness = t // f
            if a <= ness:
                continue
            cnt += a - ness

        if cnt > K:
            return False
        else:
            return True

    ng = -1
    ok = A[-1] * F[0]

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


sol()

Solution (Python):
def fun(m):
    ans = 0
    for i in range(n):
        ans += max(a[i] - m//f[i], 0)
    if ans<=m_:
        return True
    return False

n,m_ = [int(j) for j in input().split()]
a = [int(j) for j in input().split()]
f = [int(j) for j in input().split()]
a = sorted(a)
f = sorted(f)[::-1]
b = []
for i in range(n):
    b.append(a[i]*f[i])
l = 0
r = max(b)

while l<=r:
    
    m = l + (r-l)//2
    if fun(m)==True:
        r = m
        if l==r:
            break
    elif fun(m)==False:
        l = m+1
print(m)

Solution (Python):
n,k = map(int,input().split())
lis = list(map(int,input().split()))
li = list(map(int,input().split()))
lis.sort(reverse=True)
li.sort()
hi = 10 ** 12
low = 0
while hi > low+1:
    mid = (hi + low)//2
    cnt = 0
    for i in range(n):
        cnt += max(0,lis[i]-mid//li[i])
    if cnt <= k:
        hi = mid
    else:
        low = mid
    ans1 = low
    ans2 = hi
cnt = 0
for i in range(n):
    cnt += max(0,lis[i]-ans1//li[i])
if cnt <= k:
    print(ans1)
else:
    print(ans2)

Solution (Python):

def binary_search(upper_bound: int = 1 << 60, lower_bound: int = -1) -> int:
    ok, ng = upper_bound, lower_bound
    while abs(ok - ng) > 1:
        mid = (ok + ng) // 2
        if check(mid):
            ok = mid
        else:
            ng = mid
    return ok


def check(x: int) -> bool:
    cost = sum(a - x // f for a, f in zip(A, F) if a * f > x)
    return cost <= K


def main():
    global K, A, F
    N, K, *AF = map(int, open(0).read().split())
    A, F = AF[:N], AF[N:]
    A.sort(), F.sort(reverse=1)
    ans = binary_search()
    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):

def binary_search(upper_lim: int) -> int:
    ok, ng = upper_lim, -1
    while abs(ok - ng) > 1:
        mid = (ok + ng) // 2
        if check(mid):
            ok = mid
        else:
            ng = mid
    return ok


def check(x: int) -> bool:
    cost = sum(a - x // f for a, f in zip(A, F) if a * f > x)
    return cost <= K


def main():
    global K, A, F
    N, K, *AF = map(int, open(0).read().split())
    A, F = AF[:N], AF[N:]
    A.sort(), F.sort(reverse=1)
    ans = binary_search(A[-1] * F[0] + 1)
    print(ans)


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)

minT, maxT = -1, max([A[i] * F[i] for i in range(N)])
while maxT - minT > 1:
    midT = minT + (maxT - minT) // 2
    if sum([max(A[i] - midT // F[i], 0) for i in range(N)]) > K:
        minT = midT
    else:
        maxT = midT

print(maxT)

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

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

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