Автор проблеми: | Хасан Салех (MathModel) |
Підготовлено: | Хасан Салех (MathModel) |
Редагував: | Хасан Салех (MathModel) |
Розв'язок
Цільовий масив повинен бути арифметичною прогресією: b_i=m\cdot i+c. Ми можемо лише збільшувати значення, тому для фіксованого нахилу найменше можливе зсув це
Тоді загальна вартість (сума приростів) дорівнює
Нехай S=\frac{n(n+1)}{2} та A=\sum_i a_i. Визначимо
Тоді \text{cost}(m)=F(m)-A. Це точковий максимум прямих у опукла, унімо́дальна функція на цілих числах. Отже, ми можемо знайти її мінімум за допомогою стандартного дискретного опуклого пошуку (порівняти ) з f(M+1)).
Попередньо обчисліть \texttt{ba}_i=n\cdot a_i, \texttt{w}_i=S-n\cdot i. Тоді
Складність \mathcal{O}(n\log)
for _ in range(int(input())):
n=int(input())
a=list(map(int,input().split()))
S=n*(n+1)//2
ba=[n*x for x in a]
w=[S-n*(i+1) for i in range(n)]
A=sum(a)
def F(m):
z=-10**30
for i in range(n):
v=ba[i]+m*w[i]
if v>z:z=v
return z
L=-10**9
R=10**9
while L<R:
M=(L+R)//2
if F(M)<=F(M+1):R=M
else:L=M+1
assert(F(L)<=9*10**18)
print(F(L)-A)