A - ベルトコンベア / Belt Conveyor Editorial by admin
GPT 5.2 High概要
各操作は「ある作業台の部品を全部まとめて右隣へ移す(または最後なら捨てる)」だけなので、操作を順にそのままシミュレーションして最終状態を求めます。
考察
重要な観察は次の2点です。
- スイッチを押した作業台 \(i\) の変化は、作業台 \(i\) と(\(i<N\) なら)作業台 \(i+1\) にしか影響しません。
つまり、1回の操作は 局所的(定数個の要素の更新) です。 - 部品は「1個ずつ流れる」のではなく「その作業台にある分が全部一括で移動」します。
よって、毎回「移動する個数 \(x\) を取り出して隣に足し、元を0にする」だけで済みます。
素朴に「部品を1個ずつ動かす」ような実装をすると、部品数が最大で \(2\times 10^{14}\) にもなり得るため、操作1回で莫大な回数の更新が必要になってTLEになります。しかし本問題の操作は一括移動なので、部品数に依存しない \(O(1)\) 更新で処理できます。
例:\(N=4,\ A=[3,0,2,1]\) で作業台2のスイッチを押しても、\(A_2=0\) なので何も起きません。
作業台1を押すと、\(3\) 個が作業台2へ移り \([0,3,2,1]\) になります(1個ずつ動かす必要はありません)。
アルゴリズム
配列 \(A\) を「各作業台の現在の部品数」として持ち、操作を入力順に処理します。
各操作で押す作業台を \(b\)(0-index)とすると:
- もし \(b = N-1\)(最後の作業台)なら
- \(A[b] \leftarrow 0\)(ライン外に排出)
- それ以外なら
- \(x \leftarrow A[b]\)
- \(A[b] \leftarrow 0\)
- \(A[b+1] \leftarrow A[b+1] + x\)
\(A[b]=0\) のときは \(x=0\) なので何も変わらず、問題文の仕様と一致します(コードでは軽い最適化として \(x\) が0なら加算を省略しています)。
計算量
- 時間計算量: \(O(N+Q)\)(初期配列の読み込みが \(O(N)\)、各操作が \(O(1)\))
- 空間計算量: \(O(N)\)(配列 \(A\))
実装のポイント
\(N,Q \le 2\times 10^5\) なので、Pythonでは
sys.stdin.buffer.read()による一括読み込みが安全です。添字を 0-index に直すため、入力の \(B_j\) から \(1\) を引きます。
値は最大 \(2\times 10^{14}\) まで増え得ますが、Pythonの整数はオーバーフローしません。
ソースコード
import sys
def main():
it = iter(map(int, sys.stdin.buffer.read().split()))
N = next(it)
Q = next(it)
A = [next(it) for _ in range(N)]
for _ in range(Q):
b = next(it) - 1
if b == N - 1:
A[b] = 0
else:
x = A[b]
if x:
A[b] = 0
A[b + 1] += x
sys.stdout.write(" ".join(map(str, A)))
if __name__ == "__main__":
main()
この解説は gpt-5.2-high によって生成されました。
posted:
last update: