Минимальные затраты на установку пружин одинаковой длины

Я работаю над следующей задачей:

Вам дана отсортированная коллекция пружин. Каждый из них изготовлен в определенных размерах, и каждое растяжение или сжатие требует немалого усилия. Чтобы удлинить или укоротить пружину, которая еще не сдвинулась ни на сантиметр, требуется 1 единица усилия. Каждое последующее растяжение или сжатие одной и той же пружины требует дополнительной 1 единицы усилия. Точнее, если вы хотите удлинить пружину на D сантиметров, она приложится на 1,2,…,D последовательные единицы усилия.

Ваша задача — ответить на q вопросов о том, сколько минимальных усилий потребуется, чтобы установить одинаковую длину k-кратчайших пружин.

Ограничения: N,Q <= 106, xi <= 109

Вход: Н, В
х1, х2, х3, ...
д1, д2, д3, ...

N - количество пружин
xi - длина i-й пружины (Обратите внимание, что xi <= xi+1)
qi - сколько пружин нужно поставить одинаковой длины в i-м вопросе

Выход: Ответы на вопросы - минимальных усилий потребуется, чтобы установить к-кратчайшие пружины одинаковой длины. Потому что ответ может быть крупным шрифтом по модулю 10^9+7.

Моя попытка решения: Я обнаружил, что минимальное усилие будет достигнуто, если пружины будут установлены на среднюю длину пружин. Однако в этом подходе сложность алгоритма составляет O(n*q), что слишком медленно для данных ограничений.

Как я могу решить эту проблему быстрее?

В своем жестком подходе я рассчитываю среднюю длину пружин, а затем линейно рассчитываю стоимость каждой пружины. Это слишком медленно для N,Q <= 106, но достаточно для n,q <= 103.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Общее усилие пружины с начальной длиной x и целевой длиной v пропорционально (x-v)2.

Для группы из N пружин Sum[(xi-v)2] = Sum[xi2] - 2v*Sum[xi] +Nv2

Обратите внимание, что суммирование вообще не зависит от целевой длины, поэтому вы можете просто предварительно вычислить Sum[xi2] и Sum[xi] для всех префиксов вашего массива за время O(n).

Затем для каждого запроса вы можете найти соответствующие суммы и вычислить минимальную стоимость для любого v за время O(1), что в сумме даст O(n+q).

Как вы уже определили, целевая длина минимального усилия — это средняя длина пружины Sum[xi]/N. Это не всегда будет целое число, поэтому просто попробуйте два целых числа по обе стороны от него.

Применение модуля к ответу — это задание, оставленное читателю.

Matt Timmermans 03.08.2024 15:52

Хотя, если вы действительно хотите применить это к длинам, вы можете сделать это, отслеживая самый большой разрыв в длине и решая, будет ли лучше добавить 10^9+7 к предшествующим ему длинам.

Matt Timmermans 03.08.2024 15:54

Спасибо за помощь. Я не думал, что решение будет таким простым, и без проблем попробовал использовать решение O(q*log(n)).

randomAlgo 03.08.2024 15:59

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

Matt Timmermans 03.08.2024 16:10

Можем ли мы использовать пространство O(1), если упорядочим запросы и добавим обновления на основе количества обновленных элементов и их суммы? До конца не дочитал, но думаю так.

גלעד ברקן 03.08.2024 18:07

@גלעדברקן Если вы упорядочиваете запросы, вам не нужно запоминать какие-либо суммы... но вам нужно запомнить все результаты запроса, чтобы вы могли выводить их в правильном порядке. Тогда это не пространство O(1).

Matt Timmermans 03.08.2024 18:11

Хех, хороший момент!

גלעד ברקן 03.08.2024 23:45

Другие вопросы по теме