結果

問題 No.704 ゴミ拾い Medium
ユーザー lam6er
提出日時 2025-04-15 21:11:52
言語 PyPy3
(7.3.15)
結果
AC  
実行時間 707 ms / 1,500 ms
コード長 2,016 bytes
コンパイル時間 167 ms
コンパイル使用メモリ 81,908 KB
実行使用メモリ 253,488 KB
最終ジャッジ日時 2025-04-15 21:18:03
合計ジャッジ時間 17,072 ms
ジャッジサーバーID
(参考情報)
judge4 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 4
other AC * 44
権限があれば一括ダウンロードができます

ソースコード

diff #

import bisect

def main():
    import sys
    input = sys.stdin.read().split()
    ptr = 0
    n = int(input[ptr])
    ptr += 1
    a = list(map(int, input[ptr:ptr + n]))
    ptr += n
    x = list(map(int, input[ptr:ptr + n]))
    ptr += n
    y = list(map(int, input[ptr:ptr + n]))
    ptr += n

    INF = float('inf')

    class SegmentTree:
        def __init__(self, size):
            self.n = 1
            while self.n < size:
                self.n <<= 1
            self.size = size
            self.tree = [INF] * (2 * self.n)

        def update(self, pos, val):
            pos += self.n
            self.tree[pos] = val
            while pos > 1:
                pos >>= 1
                self.tree[pos] = min(self.tree[2 * pos], self.tree[2 * pos + 1])

        def query(self, l, r):
            res = INF
            l += self.n
            r += self.n
            while l <= r:
                if l % 2 == 1:
                    res = min(res, self.tree[l])
                    l += 1
                if r % 2 == 0:
                    res = min(res, self.tree[r])
                    r -= 1
                l >>= 1
                r >>= 1
            return res

    left_segment = SegmentTree(n)
    right_segment = SegmentTree(n)

    dp = [0] * n

    for i in range(n):
        if i == 0:
            prev_dp = 0
        else:
            prev_dp = dp[i - 1]
        current_x = x[i]
        current_y = y[i]
        left_val = current_y - current_x + prev_dp
        right_val = current_x + current_y + prev_dp
        left_segment.update(i, left_val)
        right_segment.update(i, right_val)

        a_i = a[i]
        m = bisect.bisect_right(x, a_i, 0, i + 1) - 1

        min_left = INF
        if m >= 0:
            min_left = left_segment.query(0, m) + a_i

        min_right = INF
        if m + 1 <= i:
            min_right = right_segment.query(m + 1, i) - a_i

        dp_i = min(min_left, min_right)
        dp[i] = dp_i

    print(dp[-1])

if __name__ == '__main__':
    main()
0