結果
| 問題 | 
                            No.1095 Smallest Kadomatsu Subsequence
                             | 
                    
| コンテスト | |
| ユーザー | 
                             lam6er
                         | 
                    
| 提出日時 | 2025-03-20 20:34:41 | 
| 言語 | PyPy3  (7.3.15)  | 
                    
| 結果 | 
                             
                                AC
                                 
                             
                            
                         | 
                    
| 実行時間 | 921 ms / 2,000 ms | 
| コード長 | 3,759 bytes | 
| コンパイル時間 | 164 ms | 
| コンパイル使用メモリ | 82,372 KB | 
| 実行使用メモリ | 170,392 KB | 
| 最終ジャッジ日時 | 2025-03-20 20:36:31 | 
| 合計ジャッジ時間 | 11,878 ms | 
| 
                            ジャッジサーバーID (参考情報)  | 
                        judge3 / judge2 | 
(要ログイン)
| ファイルパターン | 結果 | 
|---|---|
| sample | AC * 3 | 
| other | AC * 30 | 
ソースコード
import sys
import bisect
inf = float('inf')
class SegmentTree:
    def __init__(self, max_size):
        self.N = 1
        while self.N < max_size:
            self.N <<= 1
        self.size = self.N
        self.tree = [inf] * (2 * self.N)
    
    def update_point(self, pos, value):
        pos += self.N
        if self.tree[pos] > value:
            self.tree[pos] = value
            pos >>= 1
            while pos >= 1:
                new_val = min(self.tree[2*pos], self.tree[2*pos+1])
                if self.tree[pos] == new_val:
                    break
                self.tree[pos] = new_val
                pos >>= 1
    
    def query_range(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
def main():
    input = sys.stdin.read().split()
    N = int(input[0])
    A = list(map(int, input[1:N+1]))
    
    sorted_A = sorted(A)
    rank = {v:i for i, v in enumerate(sorted_A)}
    r = [rank[a] for a in A]
    max_rank = len(sorted_A) - 1
    
    # Compute min_left_less and min_left_greater
    left_st = SegmentTree(max_rank + 1)
    min_left_less = [inf] * N
    min_left_greater = [inf] * N
    for j in range(N):
        current_r = r[j]
        # Query for min_left_less
        if current_r > 0:
            q_l = 0
            q_r = current_r - 1
            min_val = left_st.query_range(q_l, q_r)
        else:
            min_val = inf
        min_left_less[j] = min_val
        # Query for min_left_greater
        if current_r + 1 <= max_rank:
            q_l = current_r + 1
            q_r = max_rank
            min_val = left_st.query_range(q_l, q_r)
        else:
            min_val = inf
        min_left_greater[j] = min_val
        # Update left_st
        left_st.update_point(current_r, A[j])
    
    # Compute min_right_less and min_right_greater
    right_st = SegmentTree(max_rank + 1)
    min_right_less = [inf] * N
    min_right_greater = [inf] * N
    for j in range(N-1, -1, -1):
        current_r = r[j]
        # Query for min_right_less
        if current_r > 0:
            q_l = 0
            q_r = current_r - 1
            min_val = right_st.query_range(q_l, q_r)
        else:
            min_val = inf
        min_right_less[j] = min_val
        # Query for min_right_greater
        if current_r + 1 <= max_rank:
            q_l = current_r + 1
            q_r = max_rank
            min_val = right_st.query_range(q_l, q_r)
        else:
            min_val = inf
        min_right_greater[j] = min_val
        # Update right_st
        right_st.update_point(current_r, A[j])
    
    ans = inf
    # Check each possible middle element j (i < j < k)
    for j in range(1, N-1):  # j ranges from 1 to N-2 inclusive
        # Case 1: j is the max, so we need elements < A[j] on both sides
        case1_sum = inf
        left_less = min_left_less[j]
        right_less = min_right_less[j]
        if left_less != inf and right_less != inf:
            case1_sum = left_less + A[j] + right_less
        
        # Case 2: j is the min, so we need elements > A[j] on both sides
        case2_sum = inf
        left_greater = min_left_greater[j]
        right_greater = min_right_greater[j]
        if left_greater != inf and right_greater != inf:
            case2_sum = left_greater + A[j] + right_greater
        
        current_min = min(case1_sum, case2_sum)
        if current_min < ans:
            ans = current_min
    
    print(ans if ans != inf else -1)
if __name__ == '__main__':
    main()
            
            
            
        
            
lam6er