Задача 3. Метрострой

Входной файл:Стандартный вход   Ограничение времени:1 сек
Выходной файл:Стандартный выход   Ограничение памяти:512 Мб
Максимальный балл:100  

Условие

Буровая установка «Мегабур 2022» для прокладки туннелей метро Байтсбурга имеет n двигателей. Питание установки устроено таким образом, что на все двигатели подается одно и то же целочисленное напряжение x.

У каждого двигателя есть два режима, если на него подается напряжение x, то i-й двигатель работает в первом режиме, если x ≤ zi и во втором режиме, если x > zi.

При этом i-й двигатель характеризуется удельной мощностью ai в первом режиме и bi во втором режиме. Это означает, что увеличение напряжения на 1 когда двигатель находится в первом режиме, приводит к увеличению его мощности на ai, а во втором режиме приводит к увеличению его мощности на bi. Иначе говоря, при подаче напряжения x, если i-й двигатель находится в первом режиме он работает с мощностью ai x, а если во втором режиме, то с мощностью ai zi + bi(x − zi).

Для прокладки туннеля суммарная мощность двигателей должна быть не меньше p. Какое минимальное целочисленное напряжение необходимо подать на установку, чтобы суммарная мощность двигателей была больше или равна p?

Формат входных данных

Первая строка ввода содержит целые числа n и p.

Следующие n строк описывают двигатели и содержат по три целых числа zi, ai, bi.

Формат выходных данных

Требуется вывести одно целое число — минимальное напряжение, которые необходимо подать на установку.

Ограничения

1 ≤ n ≤ 100, 1 ≤ p ≤ 1012

1 ≤ zi ≤ 109, 1 ≤ ai, bi ≤ 104

Примеры тестов

Стандартный вход Стандартный выход
1
1 6
4 1 2
5
2
3 15
2 3 3
4 2 1
5 2 2
3

Разбор

Автор задачи: Андрей Станкевич

Подзадача 1

Заметим, что если двигатель всего один, то существует два случая: необходимая мощность достигается при работе двигателя в первом режиме или во втором. При этом легко понять, какой режим необходим, если сравнить z1 a1 и p. Таким образом, решение первой подзадачи выглядит так:


if p <= z[0] * a[0]:
    print(ceil(p / a))
else:
    print(z + ceil((p - z[0] * a[0]) / b)

Подзадача 2

Ограничения этой подзадачи позволяли явно перебрать и найти минимальный x, удовлетворяющий условию задачи.


x = 1
while True:
    q = 0
    for i in range(n):
        if x <= z[i]:
            q += a[i] * x
        else:
            q += a[i] * z[i] + b[i] * (x - z[i])
    if q >= p:
        break
    c += 1

print(x)

Подзадача 3

Третья подзадача также предполагала два случая: необходимую мощность можно получить, если двигатели работают в первом режиме, или необходим второй режим.

Первый случай выполняется, если ni = 1ai z1 ⩾ p. В таком случае, ответ — pni = 1ai, округленное вверх. Иначе, ответ можно найти как p − ni = 1ai z1ni = 1bi.

Подзадача 4

Будем считать, что z1 ⩽ z2 (если это не так, мысленно перенумеруем двигатели). Тогда:
  1. либо оба двигателя будут работать в первом режиме (x ∈ [0, z1)), тогда ответ — ceil(pa1 + a2);
  2. либо двигатель 1 будет работать во втором режиме, а двигатель 2 — в первом (x ∈ [z1, z2)), тогда ответ — ceil(p − (a1 + a2) ⋅ z1b1 + a2);
  3. либо оба будут прокладывать туннель во втором режиме (x ∈ [z2, ∞)), ответ в этом случае — ceil(p − (a1 + a2) ⋅ z1 − (b1 + a2) ⋅ (z2 − z1)b1 + b2).

Давайте для каждого случая почитаем минимальный x и выберем первый случай, в котором x попадает в заданный полуинтервал возможных значений x.

Здесь намеренно не рассматривается отдельно случай, когда z1 = z2, это возможно так как не существует таких x, которые попадают в полуинтервал [z1, z2) = varnothing .

Полное решение, способ 1

Давайте обобщим решение предыдущей подзадачи на n > 2. Отсортируем двигатели по zi. Точно так же у нас будет n + 1 непересекающийся полуинтервал, объединение таких полуинтервалов будет давать числовой луч [0,  + ∞).

В каждом интервале [zi, zi + 1) (считаем, что z0 = 0 и zn + 1 = ∞) можно находить минимальный x при котором достигается необходимая мощность, как p − S(i)j − 1i = 1bi + ni = jai, округленное вверх. Функцией S(i) здесь обозначена мощность, которая достигается при x = zi, ее можно найти по формуле i − 1k = 1(zk − zk − 1)(k − 1i = 1bi + ni = kai).

Таким образом, в решении нужно последовательно рассматривать интервалы до тех пор, пока не найдем x, дающий достаточную мощность такой и лежащий в этом интервале.

Время работы такого решения O(n2) или O(nlog n), если немного оптимизировать.

Полное решение, способ 2

Заметим, что мощность, которую дают двигатели, монотонно возрастает при увеличении x. Поэтому для нахождения минимального x можно воспользоваться бинарным поиском, на каждой итерации проверяя, в каком режиме работает каждый из двигателей.

Время работы такого решения O(nlog n).


0.092s 0.010s 13