結果
問題 | No.3017 交互浴 |
ユーザー |
|
提出日時 | 2025-02-05 15:03:53 |
言語 | PyPy3 (7.3.15) |
結果 |
TLE
|
実行時間 | - |
コード長 | 3,965 bytes |
コンパイル時間 | 701 ms |
コンパイル使用メモリ | 82,372 KB |
実行使用メモリ | 371,524 KB |
最終ジャッジ日時 | 2025-02-05 15:04:37 |
合計ジャッジ時間 | 36,688 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 50 TLE * 5 |
ソースコード
def solve():import sys, bisectdata = sys.stdin.buffer.read().split()if not data:returnN = int(data[0])# H_i の読み込みHs = [int(x) for x in data[1:1+N]]# 状態管理:segments と endpoints# segments はリスト [(L, R, col)],端点 endpoints[i] = R (区間 [L, R) の右端)# 状態は常に [0, current_max) をカバーする(current_max は segments[-1][1])segments = [] # 初めは状態未定義(まだ入浴していない状態は全身緑だが,水色部分は 0 なので管理不要)endpoints = [] # 各区間の右端current_max = 0waterblue = 0 # 現在の水色の全長out_lines = []# 1-indexed 入浴for i, h in enumerate(Hs, start=1):# 入浴 i の色: 奇数→水色 (1), 偶数→緑 (0)new_col = 1 if (i & 1) else 0if current_max < h:# [0, h) を新色に更新.# 以前の状態([0, current_max))は全て上書き,さらに [current_max, h) を新たに拡張.segments = [(0, h, new_col)]endpoints = [h]current_max = hwaterblue = h if new_col == 1 else 0else:# current_max >= h# 旧状態:segments で表す [0, current_max) のうち,[0, h) を新色に上書きする.# まず,更新前の [0, h) の水色長を求める# segments は [0, current_max) で連続している.# 右端のリスト endpoints を使って,更新区間 h が含まれる区間の位置 pos を求めるpos = bisect.bisect_left(endpoints, h)# ここで,pos は segments[pos] が h を超える(または等しい)区間であることを意味する.removed_blue = 0# 先頭から pos まで(pos の手前まで)は完全に [L,R) ∘ [0, h) に含まれるfor j in range(pos):L, R, col = segments[j]if col == 1:removed_blue += (R - L)# pos 番目(存在する場合)は部分的に上書きif pos < len(segments):L, R, col = segments[pos]if h > L and col == 1:removed_blue += (h - L)# 更新後,新たに [0, h) は new_col になる.new_blue = h if new_col == 1 else 0waterblue = waterblue - removed_blue + new_blue# 状態更新:新たな状態は# [0, h) : new_col# もし pos 番目の区間が [L, R, col] で h < R なら,その区間の [h, R) 部分を残す.# その後は segments[pos+1:] をそのまま残す.new_segments = [(0, h, new_col)]new_endpoints = [h]if pos < len(segments):L, R, col = segments[pos]if h < R:new_segments.append((h, R, col))new_endpoints.append(R)pos += 1# その後,pos 以降の区間を連結if pos < len(segments):new_segments.extend(segments[pos:])new_endpoints.extend(endpoints[pos:])# 状態更新segments = new_segmentsendpoints = new_endpoints# もし先頭の2区間が同色なら結合if len(segments) >= 2 and segments[0][2] == segments[1][2]:# 結合して [0, segments[1][1]) にするmerged = (0, segments[1][1], segments[0][2])segments[0] = mergedendpoints[0] = merged[1]del segments[1]del endpoints[1]# current_max は変化なしout_lines.append(str(waterblue))sys.stdout.write("\n".join(out_lines))if __name__ == '__main__':solve()