E - お花見の予算チェック / Cherry Blossom Viewing Budget Check Editorial by admin
GPT 5.2 High概要
各クエリで指定された区間 \([L, R]\) の合計金額が予算上限 \(T\) を超えるかを判定します。多数の区間和を高速に求めるために累積和を使います。
考察
各買い出しで必要なのは区間和 \(A_L + A_{L+1} + \cdots + A_R\) です。
素朴に毎回 \(L\) から \(R\) まで足し合わせると、1回のクエリが最悪 \(O(N)\) かかり、全体で \(O(NQ)\) になります。制約では \(N, Q \le 2 \times 10^5\) なので、最悪だと約 \(4 \times 10^{10}\) 回の加算になり、時間内に終わりません(TLE)。
ここで重要な気づきは、区間和は累積和で一発計算できるということです。
累積和 \(pref[i] = A_1 + A_2 + \cdots + A_i\) を用意すると、
- 区間 \([L, R]\) の和は
\(pref[R] - pref[L-1]\)
で求められます。これなら各クエリは \(O(1)\) です。
例:\(A = [3, 1, 4, 1, 5]\) のとき
\(pref = [0, 3, 4, 8, 9, 14]\)(先頭に \(pref[0]=0\) を置く)
区間 \([2,4]\) の和は \(pref[4]-pref[1]=9-3=6\) となります。
アルゴリズム
- 長さ \(N+1\) の配列 \(pref\) を用意し、\(pref[0]=0\) とする。
- \(i=1\) から \(N\) まで順に、\(pref[i] = pref[i-1] + A_i\) を計算する(累積和)。
- 各クエリ \((L, R)\) について
- \(total = pref[R] - pref[L-1]\) を求める
- \(total > T\) なら
Yes、そうでなければNoを出力する
計算量
- 時間計算量: 前処理が \(O(N)\)、各クエリが \(O(1)\) なので合計 \(O(N+Q)\)
- 空間計算量: 累積和配列に \(O(N)\)
実装のポイント
累積和は \(pref[0]=0\) を置くと、\(L=1\) のときも同じ式 \(pref[R]-pref[L-1]\) で扱えて楽です。
合計金額や \(T\) は最大で \(10^{14}\) 規模になり得るため、言語によっては 64bit 整数が必要です(Python は整数が大きくても扱えます)。
出力はクエリ数が多いので、文字列を配列に溜めて最後にまとめて出すと高速です。
ソースコード
import sys
def main():
input = sys.stdin.readline
N, Q, T = map(int, input().split())
A = list(map(int, input().split()))
pref = [0] * (N + 1)
s = 0
for i, x in enumerate(A, 1):
s += x
pref[i] = s
out_lines = []
for _ in range(Q):
L, R = map(int, input().split())
total = pref[R] - pref[L - 1]
out_lines.append("Yes" if total > T else "No")
sys.stdout.write("\n".join(out_lines))
if __name__ == "__main__":
main()
この解説は gpt-5.2-high によって生成されました。
posted:
last update: