結果

問題 No.1071 ベホマラー
ユーザー lam6er
提出日時 2025-03-20 20:32:51
言語 PyPy3
(7.3.15)
結果
AC  
実行時間 93 ms / 2,000 ms
コード長 2,004 bytes
コンパイル時間 297 ms
コンパイル使用メモリ 82,560 KB
実行使用メモリ 93,120 KB
最終ジャッジ日時 2025-03-20 20:33:45
合計ジャッジ時間 2,918 ms
ジャッジサーバーID
(参考情報)
judge4 / judge3
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 5
other AC * 20
権限があれば一括ダウンロードができます

ソースコード

diff #

import bisect

def main():
    import sys
    input = sys.stdin.read
    data = input().split()
    
    n = int(data[0])
    K = int(data[1])
    X = int(data[2])
    Y = int(data[3])
    A = list(map(int, data[4:4 + n]))
    
    m_min_list = []
    for a in A:
        if a == 1:
            m_min_list.append(0)
        else:
            m_min = (a - 1 + K - 1) // K
            m_min_list.append(m_min)
    
    m_min_list.sort()
    n_list = len(m_min_list)
    if n_list == 0:
        print(0)
        return
    
    # Prepare prefix sum array from the end
    prefix_sum = [0] * (n_list + 1)
    for i in range(n_list - 1, -1, -1):
        prefix_sum[i] = prefix_sum[i + 1] + m_min_list[i]
    
    M_max = m_min_list[-1]
    
    # Binary search for the best m that maximizes the condition Y <= X * count(m)
    low = 0
    high = M_max
    best_m = 0
    while low <= high:
        mid = (low + high) // 2
        pos = bisect.bisect_right(m_min_list, mid)
        cnt = n_list - pos
        if Y <= X * cnt:
            best_m = mid
            low = mid + 1
        else:
            high = mid - 1
    
    # Generate candidate m values including best_m and surrounding values
    candidates = [
        best_m - 2, best_m - 1, best_m, best_m + 1, best_m + 2,
        M_max, 0
    ]
    # Remove duplicates and out of range values
    valid_candidates = []
    seen = set()
    for m in candidates:
        if 0 <= m <= M_max and m not in seen:
            seen.add(m)
            valid_candidates.append(m)
    # Also add M_max if not already included
    if M_max not in seen:
        valid_candidates.append(M_max)
    
    min_cost = float('inf')
    for m in valid_candidates:
        pos = bisect.bisect_right(m_min_list, m)
        cnt = n_list - pos
        sum_upper = prefix_sum[pos]
        sum_needs = sum_upper - m * cnt
        cost = Y * m + X * sum_needs
        if cost < min_cost:
            min_cost = cost
    
    print(min_cost)

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