いもす法で区間更新を差分にする
すべての区間加算が終わった後の結果だけ必要なら、変化が始まる点と終わる点だけ記録します。
言語:Python / 計算量:O(N+Q)
考え方
- [l,r) にxを加えるなら d[l]+=x、d[r]-=x。
- 最後に左から累積和を取ります。
- 更新途中に質問する場合は別の構造が必要です。
具体例
長さ5へ [1,4) に2を加えると差分は[0,2,0,0,-2,0]。累積すると[0,2,2,2,0]です。
実装
n=5;d=[0]*(n+1)
d[1]+=2;d[4]-=2
s=0;a=[]
for i in range(n):s+=d[i];a.append(s)
print(a)注意する条件
右端を含む[l,r]なら打ち消しはr+1です。半開区間の表記と混ぜないでください。
確認問題
長さ5の0配列の[1,4)に2加算。全体和は?
解答と理由
6
添字1,2,3の3要素に2ずつなので6。
実装課題
N Q と Q 行の l r x。初期値0の長さN配列の[l,r)にxを加える。最終配列を出す。N,Q≤200000、|x|≤10^9。
入力:
5 1
1 4 2
出力:
0 2 2 2 0参考実装
n,q=map(int,input().split());d=[0]*(n+1)
for _ in range(q):
l,r,x=map(int,input().split());d[l]+=x;d[r]-=x
s=0;a=[]
for i in range(n):s+=d[i];a.append(s)
print(*a)