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 heapq import heappush, heappop
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):
    red = 0
    for i in range(n):
        if a[i] * f[i] > x:
            red += a[i] - x // f[i]

    return (red <= k)


lb = -1  
ub = max([a[i] * f[i] for i in range(n)])  
while ub - lb > 1:
    mid = (ub + lb) // 2
    if check(mid):
        ub = mid
    else:
        lb = mid

print(ub)

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)

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

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

ok = 10**12+1
ng = 0

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

Solution (Python):

import sys
sys.setrecursionlimit(200000)
input = sys.stdin.readline
def ii(): return int(input())
def mi(): return map(int, input().rstrip().split())
def lmi(): return list(map(int, input().rstrip().split()))
def fi(): return float(input())
def mfi(): return map(float, input().rstrip().split())
def lmfi(): return list(map(float, input().rstrip().split()))
def li(): return list(input().rstrip())
def debug(*args, sep=" ", end="\n"): print("debug:", *args, file=sys.stderr, sep=sep, end=end) if not __debug__ else None
def exit(*arg): print(*arg); sys.exit()


import heapq
class Heapq:
    def __init__(self, arr, desc=False):
        if desc:
            arr = [-a for a in arr]
        self.sign = -1 if desc else 1
        self.hq = arr
        heapq.heapify(self.hq)

    def pop(self):
        return heapq.heappop(self.hq) * self.sign

    def push(self, a):
        heapq.heappush(self.hq, a * self.sign)

    def top(self):
        return self.hq[0] * self.sign

def main():
    N, K = mi()
    A = lmi()
    F = lmi()
    A.sort()
    F.sort()
    F.reverse()
    ng = -1
    ok = 10**12
    while ok - ng > 1:
        mid = (ok + ng) // 2
        t = 0
        for i in range(N):
            t += max(A[i] - mid // F[i], 0)
        if t <= K:
            ok = mid
        else:
            ng = mid
    print(ok)
    return


if __name__ == '__main__':
    main()

Solution (Python):
from sys import stdin


def input():
    return stdin.readline()[:-1]


def intput():
    return int(input())


def sinput():
    return input().split()


def intsput():
    return map(int, sinput())


n, k = intsput()

a = list(intsput())
f = list(intsput())

a.sort()
f.sort(reverse=True)
p = [a[i] * f[i] for i in range(n)]
scrap = [0] * n

start = 0
end = max(p)
target = (start + end) // 2
while start != end:
    cnt = 0
    for i in range(n):
        fix = 0
        if p[i] > target:
            fix = (p[i] - target + f[i] - 1) // f[i]
            cnt += fix
        
        if cnt > k:
            start = target + 1
            target = (start + end) // 2
            break
    else:
        end = target
        target = (start + end) // 2

print(start)

Solution (Python):

import sys
import math
sys.setrecursionlimit(10**8)
input = sys.stdin.readline
INF = 10**15

n, k = [int(item) for item in input().split()]
a = [int(item) for item in input().split()]
f = [int(item) for item in input().split()]
a.sort()
f.sort(reverse=True)

l = -1; r = 10**12 + 1 
while r - l > 1:
    mid = (l + r) // 2
    syugyo = 0
    for aa, ff in zip(a, f):
        target = mid // ff
        syugyo += max(aa - target, 0)
    if syugyo <= k:
        r = mid
    else:
        l = mid
print(r)

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

def chk(x):
  ct=0
  for i in range(n):
    a,f=A[i],F[-i-1]
    ct+=max(0,a-x//f)
    if ct>k:
      return False
  if ct<=k:
    return True
  else:
    return False
l=0
r=0
for i in range(n):
  r=max(r,A[i]*F[-i-1])

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

if chk(l):
  print(l)
else:
  print(r)

Solution (Python):




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


import sys
sys.setrecursionlimit(10**6)
readline = sys.stdin.readline 

from heapq import *


n,k = [int(i) for i in readline().split()]
a = [int(i) for i in readline().split()]
f = [int(i) for i in readline().split()]

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


def isOK(c):
    res = 0
    for ai,fi in zip(a,f):
        p = max(0,(ai*fi-c+fi-1)//fi)
        res += p

    return res <= k
   

print(binarysearch(10**12,-1,isOK))

"""
res = 0
for i in range(n):
    while a[i]*f[i] > 12:
        a[i] -= 1
        res += 1
        
print(res)        
"""

Solution (Python):
N, K = map(int, input().split())
As = list(map(int, input().split()))
Fs = list(map(int, input().split()))
As.sort()
Fs.sort(reverse=True)
def check(x):
  k = 0
  for i in range(N):
    k += max(0, As[i]-x//Fs[i])
  return k <= K
a = 0
b = As[-1]*Fs[0]
while a < b:
  i = (a + b)//2
  if check(i):
    b = i
  else:
    if a == i:
      break
    a = i
r = b
print(r)

Solution (Python):
n,k=map(int,input().split())
a=[int(i) for i in input().split()]
f=[int(i) for i in input().split()]
lo=0 
from math import ceil 
a.sort()
f.sort(reverse=1)
def check(mi):
    cost=0 
    for i in range(n): 
        curr=a[i]*f[i]
        if curr<mi:
            pass 
        else: 
            cost+=ceil((curr-mi)/(f[i]))
            if cost>k:
                return 0 
    return cost<=k 
hi=10**13
while lo<=hi: 
    mi=(lo+hi)>>1 
    if check(mi):
        ans=mi 
        hi=mi-1 
    else:
        lo=mi+1 
print(ans)

Solution (Python):
import sys

stdin = sys.stdin

ni = lambda: int(ns())
na = lambda: list(map(int, stdin.readline().split()))
ns = lambda: stdin.readline().rstrip()  

n, k = na()
a = na()
f = na()
a.sort()
f.sort()

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


low = -1; high = 2000000000000
while high - low > 1:
    h = high+low>>1
    if ok(h, a, f, k):
        high = h
    else:
        low = h
print(high)

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()
ok = 10**12
ng = -1
while ng+1 < ok:
    c = (ok+ng) // 2
    k = K
    for a, f in zip(A, F):
        k -= max(0, a - c//f)
    if k >= 0:
        ok = c
    else:
        ng = c
print(ok)

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 solve(mid):
    tmp = [0]*n
    for i in range(n):
        tmp[i] = mid // f[i]
    res = 0
    for i in range(n):
        if tmp[i] < a[i]:
            res += a[i] - tmp[i]
    
    if res <= k:
        return True
    else:
        return False
     
ok = 10**12 + 1
ng = 0

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

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


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

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

print(ok)

Solution (Python):
n,k=map(int,input().split())
a=list(map(int,input().split()))
f=list(map(int,input().split()))
a.sort(reverse=True)
f.sort()
mx=10**12
mn=-1
def test(buf):
    count=0
    for i in range(n):
        count+=max(0,a[i]-buf//f[i])
        if count>k:
            return False
    return True

while mx-mn>1:
    buf=(mx+mn)//2
    if test(buf):
        mx=buf
    else:
        mn=buf
print(mx)

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

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

def possible(x):
    k = K
    for i in range(N):
        if A[i]*F[i]>x:
            k -= ceil(A[i]-x/F[i])
        if k < 0:
            break
    return k >= 0


l = 0
r = 10**12
for i in range(45):
    m = (l+r)/2
    if possible(m):
        r = m
    else:
        l = m

print(round(m))

Solution (Python):
import math

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

A_list = list(map(int, input().strip().split()))
F_list = list(map(int, input().strip().split()))

A_list.sort()
F_list.sort()
F_list.reverse()

def check(score):
	k = K
	for a, f in zip(A_list, F_list):
		if a * f > score:
			t = math.floor(score / f)
			k -= a - t
			if k < 0:
				return False
	return True

score_min = 0
score_max = (10 ** 6) * (10 ** 6) * (10 ** 5)
while score_min < score_max:
	score = (score_max + score_min) // 2
	if check(score):
		score_max = score
	else:
		score_min = score + 1

print(score_min)

Solution (Python):

from collections import defaultdict,deque
from heapq import heappush, heappop
import sys
import math
import bisect
import random
def LI(): return [int(x) for x in sys.stdin.readline().split()]
def I(): return int(sys.stdin.readline())
def LS():return [list(x) for x in sys.stdin.readline().split()]
def S():
    res = list(sys.stdin.readline())
    if res[-1] == "\n":
        return res[:-1]
    return res
def IR(n):
    return [I() for i in range(n)]
def LIR(n):
    return [LI() for i in range(n)]
def SR(n):
    return [S() for i in range(n)]
def LSR(n):
    return [LS() for i in range(n)]

sys.setrecursionlimit(1000000)
mod = 1000000007

def solve():
    n,k = LI()
    a = LI()
    f = LI()
    a.sort()
    f.sort(reverse = True)
    M = 0
    for i in range(n):
        M = max(M,a[i]*f[i])
    l = -1
    r = M
    while r-l > 1:
        m = (l+r)>>1
        s = 0
        for i in range(n):
            p = m//f[i]
            s += max(0,a[i]-p)
            if s > k:
                l = m
                break
        else:
            r = m
    print(r)
    return


if __name__ == "__main__":
    solve()

Solution (Python):

from heapq import heapify, heappop, heappush
from collections import defaultdict
import sys

def inpl(): return list(map(int, input().split()))

N, K = inpl()
A = sorted(inpl())
F = sorted(inpl(), reverse=True)

OK = 10**13
NG = -1

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

while abs(OK - NG) > 1:
    m = (OK + NG)//2
    if check(m):
        OK = m
    else:
        NG = m
    
print(OK)

Solution (Python):
N, K = map(int, input().split())
A = sorted(list(map(int, input().split())), reverse = True)
F = sorted(list(map(int, input().split())))
def C(m):
    res = 0
    for i, f in enumerate(F):
        a = m//f
        if A[i]<=a:
            continue
        res+=A[i]-a
    if res>K:
        return False
    return True


ng = -1
ok = 10**13
while ok-ng>1:
    mid = (ok+ng)//2
    if C(mid):
        ok = mid
    else:
        ng = mid
print(ok)

Solution (Python):
def check(N, A, F, K, mid):
    k = 0
    for i in range(N):
        x = mid // F[i]
        k += max(A[N-i-1] - x, 0)
    return k <= 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()
    lo = 0
    hi = A[-1] * F[-1]
    while lo < hi:
        mid = (lo + hi) // 2
        if check(N, A, F, K, mid):
            hi = mid
        else:
            lo = mid + 1
    print(lo)


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

l = -1
r = 10**12 + 2
mid = (l+r)//2
while r-l>1:
    m = 0
    for i in range(n):
        aa = mid // F[i]
        m += max(0, A[i]-aa)
    if m > k:
        l = mid
    else:
        r = mid
    mid = (l+r)//2

print(l+1)

Solution (Python):

from collections import defaultdict,deque
import sys,heapq,bisect,math,itertools,string,queue,copy,time
sys.setrecursionlimit(10**8)
INF = float('inf')
mod = 10**9+7
eps = 10**-7
def inp(): return int(sys.stdin.readline())
def inpl(): return list(map(int, sys.stdin.readline().split()))
def inpl_str(): return list(sys.stdin.readline().split())

N,K = inpl()
AA = inpl()
FF = inpl()

AA.sort()
FF.sort(reverse=True)


def solve(x):
    k = 0
    for i in range(N):
        A,F = AA[i],FF[i]
        k += max(0,A - (x//F))
    return k <= K

OK = 10**18
NG = -1

while OK - NG > 1:
    mid = (NG+OK)//2
    if solve(mid):
        OK = mid
    else:
        NG = mid

print(OK)

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

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

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


MIN=0
MAX=max(A)*max(F)

while MIN!=MAX:
    mid=(MIN+MAX)//2
    score=0

    for i in range(N):
        if A[i]*F[i]>mid:
            score+=A[i]-mid//F[i]

    if score<=K:
        MAX=mid
    else:
        MIN=mid+1

print(MIN)

Solution (Python):











from math import ceil


def is_ok(mid):
    remain = k
    for ff, aa in zip(f, a):
        if ff * aa > mid:
            x = ceil(aa - (mid / ff))
            if x <= aa and x <= remain:
                remain -= x
            else:
                return False
    return True


def bs():
    ng, ok = -1, 10 ** 12
    while abs(ok - ng) > 1:
        mid = (ok + ng) // 2
        if is_ok(mid):
            ok = mid
        else:
            ng = mid
    return ok


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

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

if __name__=='__main__':
    main()