結果
| 問題 |
No.1234 典型RMQ
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2020-09-19 02:25:09 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 879 ms / 2,000 ms |
| コード長 | 3,375 bytes |
| コンパイル時間 | 368 ms |
| コンパイル使用メモリ | 82,304 KB |
| 実行使用メモリ | 102,656 KB |
| 最終ジャッジ日時 | 2024-11-09 02:07:20 |
| 合計ジャッジ時間 | 18,192 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 27 |
ソースコード
import sys
input = lambda : sys.stdin.readline().rstrip()
sys.setrecursionlimit(max(1000, 10**9))
write = lambda x: sys.stdout.write(x+"\n")
### 遅延評価セグメント木
class LazySegmentTree:
def __init__(self, n, a=None):
"""初期化
num : n以上の最小の2のべき乗
"""
num = 1
while num<=n:
num *= 2
self.num = num
self.seg = [ninf] * (2*self.num-1)
self.lazy = [f0] * (2*self.num-1)
self.ls = [0]*(2*self.num-1)
self.rs = [0]*(2*self.num-1)
self.ls[0] = 0
self.rs[0] = self.num
for i in range(self.num-1):
self.ls[2*i+1] = self.ls[i]
self.rs[2*i+1] = (self.ls[i] + self.rs[i])//2
self.ls[2*i+2] = (self.ls[i] + self.rs[i])//2
self.rs[2*i+2] = self.rs[i]
if a is not None:
# O(n)で初期化
assert len(a)==n
for i in range(n):
self.seg[num-1+i] = a[i]
for k in range(num-2, -1, -1):
self.seg[k] = op(self.seg[2*k+1], self.seg[2*k+2])
def eval(self, k):
if self.lazy[k]==f0:
return
if k<self.num-1:
self.lazy[k*2+1] = composition(self.lazy[k], self.lazy[k*2+1])
self.lazy[k*2+2] = composition(self.lazy[k], self.lazy[k*2+2])
self.seg[k] = mapping(self.lazy[k], self.seg[k])
self.lazy[k] = f0
def eval_all(self):
for i in range(2*self.num-1):
self.eval(i)
def update(self,a,b,x=None,f=None):
"""A[a]...A[b-1]をxに更新する
"""
if f is None:
# 更新クエリ
f = lambda y: x
k = 0
q = [k] # k>=0なら行きがけ順
# 重なる区間を深さ優先探索
while q:
k = q.pop()
l,r = self.ls[k], self.rs[k]
if k>=0:
self.eval(k)
if r<=a or b<=l:
continue
elif a<=l and r<=b:
self.lazy[k] = composition(f, self.lazy[k])
self.eval(k)
else:
q.append(~k)
q.append(2*k+1)
q.append(2*k+2)
else:
k = ~k
self.seg[k] = op(self.seg[2*k+1], self.seg[2*k+2])
def query(self,a,b):
k = 0
l = 0
r = self.num
q = [k]
ans = ninf
# 重なる区間を深さ優先探索
while q:
k = q.pop()
l,r = self.ls[k], self.rs[k]
self.eval(k)
if r<=a or b<=l:
continue
elif a<=l and r<=b:
ans = op(ans, self.seg[k])
else:
q.append(2*k+2)
q.append(2*k+1)
# print(q, ans, l,r,a,b, self.seg[k])
return ans
n = int(input())
a = list(map(int, input().split()))
q = int(input())
# ninf = -10**9
# op = max
# mapping = lambda f,x: f(x)
# composition = lambda f1, f2: f1 if f1 is not None else f2
ninf = 10**20
op = lambda x,y: min(x,y)
mapping = lambda f,x: f+x
composition = lambda f1, f2: f1+f2
f0 = 0
sg = LazySegmentTree(n, a)
for _ in range(q):
k,l,r,c = map(int, input().split())
if k==1:
sg.update(l-1,r,f=c)
else:
print(sg.query(l-1,r))