結果
| 問題 | 
                            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 | 
ソースコード
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()
            
            
            
        
            
lam6er