E - 座席と弁当の確認 / Checking Seats and Lunches Editorial by admin Editorial for printing
Gemini 3.0 Flash (Thinking)Overview
For each of \(N\) buses, determine whether “there are enough boxed lunches,” then efficiently determine whether there are zero buses with “insufficient boxed lunches” within each of the \(M\) given intervals \([L_j, R_j]\).
Analysis
1. Determining Each Bus Individually
First, whether each bus \(i\) is “distributable” or “not distributable” can be easily determined by comparing the given \(S_i\) and \(P_i\). - If \(S_i \geq P_i\), distribution is possible (OK) - If \(S_i < P_i\), distribution is not possible (NG)
2. Naive Approach
For each rest plan (query), one could check each bus from \(L_j\) to \(R_j\) one by one. However, this method requires up to \(N\) checks per query. Since there are \(M\) queries, the worst-case time complexity is \(O(N \times M)\). In this problem, \(N, M \leq 2 \times 10^5\), so the number of operations can reach up to \(4 \times 10^{10}\), which will not finish within the time limit.
3. Speeding Up with Prefix Sums
To efficiently determine “whether there is at least one NG bus within an interval,” we use the concept of prefix sums.
First, we convert the state of each bus into a numerical value: - For bus \(i\) that is not distributable (NG): \(A_i = 1\) - For bus \(i\) that is distributable (OK): \(A_i = 0\)
Then, checking whether there exists a non-distributable bus within an interval \([L, R]\) is equivalent to checking whether the sum of \(A_i\) within the interval is 1 or more.
To compute interval sums quickly, we precompute a prefix sum array \(pref\): - \(pref[k] = A_1 + A_2 + \dots + A_k\) (the total number of NG buses from the first through the \(k\)-th bus)
With this prepared, the number of NG buses in any interval \([L, R]\) can be computed in \(O(1)\) as follows: - Number of NG buses in the interval \(= pref[R] - pref[L-1]\)
If this value is \(0\), the plan is Yes (distribution possible); if it is \(1\) or more, the plan is No (distribution not possible).
Algorithm
- For each bus \(i = 1, \dots, N\), determine whether \(S_i < P_i\).
- Store the results as an array \(A\) of \(0\)s and \(1\)s, and construct its prefix sum array \(pref\).
- For each query \((L_j, R_j)\), compute \(pref[R_j] - pref[L_j-1]\).
- If the result is \(0\), output
Yes; otherwise, outputNo.
Complexity
- Time Complexity: \(O(N + M)\)
- Building the prefix sum takes \(O(N)\), and answering each query takes \(O(1)\), so the overall complexity is \(O(N + M)\), which is sufficiently fast.
- Space Complexity: \(O(N)\)
- \(O(N)\) memory is used to store the input data and the prefix sum array.
Implementation Notes
Fast I/O: In Python, when \(N, M\) are on the order of \(2 \times 10^5\), the standard
input()may not be fast enough. It is effective to read all input at once usingsys.stdin.read().split()or similar methods.Index Adjustment: The problem statement is 1-indexed (starting from 1), but program arrays are often 0-indexed (starting from 0), so care must be taken with the range specification of prefix sums (especially the left endpoint \(L-1\)).
Source Code
import sys
def solve():
# 競技プログラミングにおいて、入力を一度に読み込んで処理するのは高速化の一般的な手法です。
# sys.stdin.read().split() は、すべての空白文字(スペース、改行など)で分割された文字列のリストを返します。
input_data = sys.stdin.read().split()
if not input_data:
return
# すべての入力文字列を整数のリストに変換します。
# これにより、インデックスによる高速なアクセスが可能になります。
data = list(map(int, input_data))
# バスの台数 N と休憩プランの数 M を取得します。
N = data[0]
M = data[1]
# 弁当の数 S_i と生徒の人数 P_i のデータが始まる位置(オフセット)を設定します。
# S_1, S_2, ..., S_N は data[2] から data[N+1] まで
# P_1, P_2, ..., P_N は data[N+2] から data[2N+1] までに格納されています。
s_offset = 2
p_offset = 2 + N
# 各バスにおいて弁当が足りない(S_i < P_i)かどうかを判定し、累積和を計算します。
# pref[k] は、バス 1 からバス k までの間で弁当が不足しているバスの総数を表します。
# これにより、任意の区間 [L, R] における不足バスの有無を O(1) で判定できます。
pref = [0] * (N + 1)
for i in range(N):
# バス (i+1) が弁当不足(配布不可)かどうかをチェック
if data[s_offset + i] < data[p_offset + i]:
pref[i+1] = pref[i] + 1
else:
pref[i+1] = pref[i]
# クエリ(休憩プラン)が始まる位置を設定します。
query_start = 2 + 2 * N
results = []
# 各休憩プランについて判定を行います。
for j in range(M):
# L_j と R_j は 1-indexed で与えられます。
L = data[query_start + 2 * j]
R = data[query_start + 2 * j + 1]
# 区間 [L, R] 内に弁当不足のバスが 1 台も存在しない場合、
# pref[R] - pref[L-1] が 0 になります。
if pref[R] - pref[L-1] == 0:
results.append("Yes")
else:
results.append("No")
# 判定結果を改行区切りで一括出力します。
sys.stdout.write("\n".join(results) + "\n")
if __name__ == "__main__":
solve()
This editorial was generated by gemini-3-flash-thinking.
posted:
last update: