結果

問題 No.1077 Noelちゃんと星々4
ユーザー 草苺奶昔
提出日時 2023-03-10 19:53:31
言語 PyPy3
(7.3.15)
結果
AC  
実行時間 101 ms / 2,000 ms
コード長 4,378 bytes
コンパイル時間 306 ms
コンパイル使用メモリ 82,376 KB
実行使用メモリ 78,176 KB
最終ジャッジ日時 2024-09-18 03:22:11
合計ジャッジ時間 2,971 ms
ジャッジサーバーID
(参考情報)
judge5 / judge4
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2
other AC * 20
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

from heapq import heappop, heappush
from typing import Tuple
INF = int(1e18)
class SlopeTrick:
__slots__ = ("_min_f", "_pq_l", "_pq_r", "add_l", "add_r")
def __init__(self):
self.add_l = 0 # -> \_/
self.add_r = 0 # \_/ <-
self._pq_l = [] #
self._pq_r = [] #
self._min_f = 0
def query(self) -> Tuple[int, int, int]:
""" `f(x), f(x)xx`"""
return self._min_f, self._top_l(), self._top_r()
def add_all(self, a: int) -> None:
"""f(x) += a"""
self._min_f += a
def add_a_minus_x(self, a: int) -> None:
"""
```
add \\__
f(x) += max(a - x, 0)
```
"""
tmp = a - self._top_r()
if tmp > 0:
self._min_f += tmp
self._push_r(a)
self._push_l(self._pop_r())
def add_x_minus_a(self, a: int) -> None:
"""
```
add __/
f(x) += max(x - a, 0)
```
"""
tmp = self._top_l() - a
if tmp > 0:
self._min_f += tmp
self._push_l(a)
self._push_r(self._pop_l())
def add_abs(self, a: int) -> None:
"""
```
add \\/
f(x) += abs(x - a)
```
"""
self.add_a_minus_x(a)
self.add_x_minus_a(a)
def clear_right(self) -> None:
"""
.
```
\\/ -> \\_
f_{new} (x) = min f(y) (y <= x)
```
"""
while self._pq_r:
self._pq_r.pop()
def clear_left(self) -> None:
"""
.
```
\\/ -> _/
f_{new} (x) = min f(y) (y >= x)
```
"""
while self._pq_l:
self._pq_l.pop()
def shift(self, a: int, b: int) -> None:
"""
```
\\/ -> \\_/
f_{new} (x) = min f(y) (x-b <= y <= x-a)
```
"""
assert a <= b
self.add_l += a
self.add_r += b
def translate(self, a: int) -> None:
"""
a
```
\\/. -> .\\/
f_{new} (x) = f(x - a)
```
"""
self.shift(a, a)
def get_destructive(self, x: int) -> int:
"""
y = f(x), f(x) broken
f.
"""
res = self._min_f
while self._pq_l:
tmp = self._pop_l() - x
if tmp > 0:
res += tmp
while self._pq_r:
tmp = x - self._pop_r()
if tmp > 0:
res += tmp
return res
def merge_destructive(self, st: "SlopeTrick"):
"""
f(x) += g(x), g(x) broken
g(x).
"""
if len(st) > len(self):
st._pq_l, self._pq_l = self._pq_l, st._pq_l
st._pq_r, self._pq_r = self._pq_r, st._pq_r
st.add_l, self.add_l = self.add_l, st.add_l
st.add_r, self.add_r = self.add_r, st.add_r
st._min_f, self._min_f = self._min_f, st._min_f
while st._pq_r:
self.add_x_minus_a(st._pop_r())
while st._pq_l:
self.add_a_minus_x(st._pop_l())
self._min_f += st._min_f
def _push_r(self, a: int) -> None:
heappush(self._pq_r, a - self.add_r)
def _top_r(self) -> int:
if not self._pq_r:
return INF
return self._pq_r[0] + self.add_r
def _pop_r(self) -> int:
val = self._top_r()
if self._pq_r:
heappop(self._pq_r)
return val
def _push_l(self, a: int) -> None:
heappush(self._pq_l, -a + self.add_l)
def _top_l(self) -> int:
if not self._pq_l:
return -INF
return -self._pq_l[0] + self.add_l
def _pop_l(self) -> int:
val = self._top_l()
if self._pq_l:
heappop(self._pq_l)
return val
def _size(self) -> int:
return len(self._pq_l) + len(self._pq_r)
def __len__(self) -> int:
return self._size()
n = int(input())
heights = list(map(int, input().split()))
sl = SlopeTrick()
for num in heights:
sl.add_abs(num)
sl.clear_right()
res = sl.query()
print(res[0])
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0