結果

問題 No.1008 Bench Craftsman
ユーザー lam6er
提出日時 2025-03-31 17:47:25
言語 PyPy3
(7.3.15)
結果
WA  
実行時間 -
コード長 2,739 bytes
コンパイル時間 150 ms
コンパイル使用メモリ 82,712 KB
実行使用メモリ 126,764 KB
最終ジャッジ日時 2025-03-31 17:48:40
合計ジャッジ時間 5,731 ms
ジャッジサーバーID
(参考情報)
judge4 / judge2
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 24 WA * 3
権限があれば一括ダウンロードができます

ソースコード

diff #

import sys

def main():
    import sys
    input = sys.stdin.read().split()
    ptr = 0
    N = int(input[ptr])
    ptr += 1
    M = int(input[ptr])
    ptr += 1

    a = list(map(int, input[ptr:ptr+N]))
    ptr += N

    people = []
    max_w = 0
    sum_w = 0
    sum_x = [0] * N  # 0-based

    for _ in range(M):
        x = int(input[ptr]) - 1  # converting to 0-based for sum_x
        ptr += 1
        w = int(input[ptr])
        ptr += 1
        people.append((x + 1, w))  # people's x is 1-based in processing
        sum_w += w
        sum_x[x] += w
        if w > max_w:
            max_w = w

    # Check c=0 case
    feasible_c0 = all(ai >= sum_w for ai in a)
    if feasible_c0:
        print(0)
        return

    # Check infinite c case (each person contributes only to x_j)
    feasible_infinite = all(sum_x[i] <= a[i] for i in range(N))
    if not feasible_infinite:
        print(-1)
        return

    # Binary search between 1 and max_w
    low = 1
    high = max_w
    answer = max_w  # initialize with maximum possible

    while low <= high:
        mid = (low + high) // 2
        diff_coeff = [0] * (N + 2)  # indexes 0..N+1 (1-based to N)
        diff_const = [0] * (N + 2)

        for x, w in people:
            # Compute left interval [max(1, x - d), x]
            d = (w - 1) // mid
            left_start = max(1, x - d)
            left_end = x
            if left_start <= left_end:
                # coeff += mid
                diff_coeff[left_start] += mid
                diff_coeff[left_end + 1] -= mid
                # const += w - mid * x
                term = w - mid * x
                diff_const[left_start] += term
                diff_const[left_end + 1] -= term

            # Compute right interval [x + 1, min(N, x + d)]
            right_start = x + 1
            right_end = min(N, x + d)
            if right_start <= right_end:
                # coeff += (-mid)
                diff_coeff[right_start] += (-mid)
                diff_coeff[right_end + 1] -= (-mid)
                # const += w + mid * x
                term = w + mid * x
                diff_const[right_start] += term
                diff_const[right_end + 1] -= term

        # Compute prefix sums for coeff and const
        current_coeff = 0
        current_const = 0
        ok = True

        for i in range(1, N + 1):
            current_coeff += diff_coeff[i]
            current_const += diff_const[i]
            total = current_coeff * i + current_const
            if total > a[i - 1]:
                ok = False
                break

        if ok:
            answer = mid
            high = mid - 1
        else:
            low = mid + 1

    print(answer)

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