Входной файл: | Стандартный вход | Ограничение времени: | 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 |
|
|
2 |
|
|
Заметим, что если двигатель всего один, то существует два случая: необходимая мощность достигается при работе двигателя в первом режиме или во втором. При этом легко понять, какой режим необходим, если сравнить z1 a1 и p. Таким образом, решение первой подзадачи выглядит так:
if p <= z[0] * a[0]:
print(ceil(p / a))
else:
print(z + ceil((p - z[0] * a[0]) / b)
Ограничения этой подзадачи позволяли явно перебрать и найти минимальный 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)
Третья подзадача также предполагала два случая: необходимую мощность можно получить, если двигатели работают в первом режиме, или необходим второй режим.
Первый случай выполняется, если n∑i = 1ai z1 ⩾ p. В таком случае, ответ — pn∑i = 1ai, округленное вверх. Иначе, ответ можно найти как p − n∑i = 1ai z1n∑i = 1bi.
Давайте для каждого случая почитаем минимальный x и выберем первый случай, в котором x попадает в заданный полуинтервал возможных значений x.
Здесь намеренно не рассматривается отдельно случай, когда z1 = z2, это возможно так как не существует таких x, которые попадают в полуинтервал [z1, z2) = varnothing .
Давайте обобщим решение предыдущей подзадачи на n > 2. Отсортируем двигатели по zi. Точно так же у нас будет n + 1 непересекающийся полуинтервал, объединение таких полуинтервалов будет давать числовой луч [0, + ∞).
В каждом интервале [zi, zi + 1) (считаем, что z0 = 0 и zn + 1 = ∞) можно находить минимальный x при котором достигается необходимая мощность, как p − S(i)j − 1∑i = 1bi + n∑i = jai, округленное вверх. Функцией S(i) здесь обозначена мощность, которая достигается при x = zi, ее можно найти по формуле i − 1∑k = 1(zk − zk − 1)(k − 1∑i = 1bi + n∑i = kai).
Таким образом, в решении нужно последовательно рассматривать интервалы до тех пор, пока не найдем x, дающий достаточную мощность такой и лежащий в этом интервале.
Время работы такого решения O(n2) или O(nlog n), если немного оптимизировать.
Заметим, что мощность, которую дают двигатели, монотонно возрастает при увеличении x. Поэтому для нахождения минимального x можно воспользоваться бинарным поиском, на каждой итерации проверяя, в каком режиме работает каждый из двигателей.
Время работы такого решения O(nlog n).