// Linear rather than binary search; Moore's algorithm import java.util.*; import java.io.*; public class TaxedRSR_slow { public static int n,m; public static int book[][]; public static long lo, hi; public static final double EPS = 1e-10; public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(in.readLine()); n = Integer.parseInt(st.nextToken()); m = Integer.parseInt(st.nextToken()); book = new int[n][2]; double minratio = Double.MAX_VALUE; double maxratio = 0; for (int i = 0; i < n; i++) { st = new StringTokenizer(in.readLine()); book[i][0] = Integer.parseInt(st.nextToken()); book[i][1] = Integer.parseInt(st.nextToken()); double r = 1.0*book[i][0]/book[i][1]; if (r < minratio) minratio = r; if (r > maxratio) maxratio = r; } lo = (long)Math.ceil(minratio); hi = n*(long)Math.ceil(maxratio); // Sort by increasing deadline: Arrays.sort(book,Comparator.comparingInt(a->a[1])); long best = search(lo,hi,hi); System.out.println(best); } public static long search(long lo, long hi, long best) { for (long mid = lo; mid <= hi; mid++) { int late = moore(mid); if (late <= m) { return mid; } } return -1; } public static int moore(long rate) { // we need to be able to quickly find the longest running time of // a job, so... Comparator runtime = new Comparator() { // finds longer of two running times: public int compare(Integer i1, Integer i2) { return book[i2][0] - book[i1][0]; } }; PriorityQueue jobs = new PriorityQueue<>(runtime); // Now run Moore's algorithm: int late = 0; long total = 0; for (int i = 0; i < n; i++) { jobs.add(i); long t = book[i][0]; total += t; int remove = -1; while (remove != i && 1.0*total/rate > book[i][1]) { remove = jobs.poll(); late++; total -= book[remove][0]; } } return late; } }