1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
| # 더 많은 정보는 42jerrykim.github.io 에서 확인하세요.
import sys
NEG_INF = -4_000_000_000_000_000_000
class Node:
__slots__ = ("sum", "pref", "suff", "best")
def __init__(self, s, p, sf, b):
self.sum = s
self.pref = p
self.suff = sf
self.best = b
def make_leaf(x):
return Node(x, x, x, x)
def identity_node():
return Node(0, NEG_INF, NEG_INF, NEG_INF)
def merge_node(a: Node, b: Node) -> Node:
if a.best == NEG_INF: return b
if b.best == NEG_INF: return a
s = a.sum + b.sum
p = max(a.pref, a.sum + b.pref)
sf = max(b.suff, b.sum + a.suff)
bst = max(a.best, b.best, a.suff + b.pref)
return Node(s, p, sf, bst)
class SegTree:
def __init__(self, arr):
self.n = len(arr) - 1 # 1-indexed
self.st = [identity_node()] * (4 * self.n)
self._build(1, 1, self.n, arr)
def _build(self, p, l, r, arr):
if l == r:
self.st[p] = make_leaf(arr[l])
return
m = (l + r) // 2
self._build(p * 2, l, m, arr)
self._build(p * 2 + 1, m + 1, r, arr)
self.st[p] = merge_node(self.st[p * 2], self.st[p * 2 + 1])
def _query(self, p, l, r, ql, qr):
if qr < l or r < ql:
return identity_node()
if ql <= l and r <= qr:
return self.st[p]
m = (l + r) // 2
L = self._query(p * 2, l, m, ql, qr)
R = self._query(p * 2 + 1, m + 1, r, ql, qr)
return merge_node(L, R)
def query_best(self, l, r):
return self._query(1, 1, self.n, l, r).best
def main():
data = sys.stdin.read().strip().split()
it = iter(data)
try:
N = int(next(it))
except StopIteration:
return
A = [0] * (N + 1)
for i in range(1, N + 1):
A[i] = int(next(it))
seg = SegTree(A)
M = int(next(it))
out_lines = []
for _ in range(M):
l = int(next(it)); r = int(next(it))
out_lines.append(str(seg.query_best(l, r)))
sys.stdout.write("\n".join(out_lines))
if __name__ == "__main__":
main()
|