結果
| 問題 | 
                            No.1117 数列分割
                             | 
                    
| コンテスト | |
| ユーザー | 
                             | 
                    
| 提出日時 | 2023-03-10 20:45:15 | 
| 言語 | PyPy3  (7.3.15)  | 
                    
| 結果 | 
                             
                                AC
                                 
                             
                            
                         | 
                    
| 実行時間 | 1,839 ms / 3,000 ms | 
| コード長 | 2,587 bytes | 
| コンパイル時間 | 261 ms | 
| コンパイル使用メモリ | 82,124 KB | 
| 実行使用メモリ | 129,796 KB | 
| 最終ジャッジ日時 | 2024-09-18 03:23:20 | 
| 合計ジャッジ時間 | 21,870 ms | 
| 
                            ジャッジサーバーID (参考情報)  | 
                        judge3 / judge2 | 
(要ログイン)
| ファイルパターン | 結果 | 
|---|---|
| sample | AC * 3 | 
| other | AC * 26 | 
ソースコード
from itertools import accumulate
from typing import Callable, Generic, List, TypeVar
E = TypeVar("E")
class SlidingWindowAggregation(Generic[E]):
    """SlidingWindowAggregation
    Api:
    1. append value to tail,O(1).
    2. pop value from head,O(1).
    3. query aggregated value in window,O(1).
    """
    __slots__ = ["_stack0", "_stack1", "_stack2", "_stack3", "_e0", "_e1", "_size", "_op", "_e"]
    def __init__(self, e: Callable[[], E], op: Callable[[E, E], E]):
        """
        Args:
            e: unit element
            op: merge function
        """
        self._stack0 = []
        self._stack1 = []
        self._stack2 = []
        self._stack3 = []
        self._e = e
        self._e0 = e()
        self._e1 = e()
        self._size = 0
        self._op = op
    def append(self, value: E) -> None:
        if not self._stack0:
            self._push0(value)
            self._transfer()
        else:
            self._push1(value)
        self._size += 1
    def popleft(self) -> None:
        if not self._size:
            return
        if not self._stack0:
            self._transfer()
        self._stack0.pop()
        self._stack2.pop()
        self._e0 = self._stack2[-1] if self._stack2 else self._e()
        self._size -= 1
    def query(self) -> E:
        return self._op(self._e0, self._e1)
    def _push0(self, value):
        self._stack0.append(value)
        self._e0 = self._op(value, self._e0)
        self._stack2.append(self._e0)
    def _push1(self, value):
        self._stack1.append(value)
        self._e1 = self._op(self._e1, value)
        self._stack3.append(self._e1)
    def _transfer(self):
        while self._stack1:
            self._push0(self._stack1.pop())
        while self._stack3:
            self._stack3.pop()
        self._e1 = self._e()
    def __len__(self):
        return self._size
INF = int(1e18)
n, k, m = map(int, input().split())
nums = list(map(int, input().split()))
def max(x, y):
    if x > y:
        return x
    return y
preSum = [0] + list(accumulate(nums))
dp = [-INF] * (n + 1)
dp[0] = 0
for _ in range(k):
    ndp = [-INF] * (n + 1)
    s1 = SlidingWindowAggregation(lambda: -INF, max)
    s2 = SlidingWindowAggregation(lambda: -INF, max)
    for i in range(n + 1):
        ndp[i] = max(ndp[i], s1.query() - preSum[i])
        ndp[i] = max(ndp[i], s2.query() + preSum[i])
        s1.append(dp[i] + preSum[i])
        s2.append(dp[i] - preSum[i])
        if len(s1) > m:
            s1.popleft()
        if len(s2) > m:
            s2.popleft()
    dp = ndp
print(dp[n])