-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathSegTree.py
More file actions
64 lines (58 loc) · 1.98 KB
/
SegTree.py
File metadata and controls
64 lines (58 loc) · 1.98 KB
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
# このセグ木はPythonだとTLEするのでPyPyを推奨します
"""
〜segfuncの使い方について〜
update(k, x): k番目の要素をxに更新する
query(l, r): [l, r)(l <= k < r の区間)から値kを取得する
"""
def segfunc(x: int, y: int) -> int:
"ここで求めたい処理を行う, max(x, y) や x ^ y など"
return x ^ y
"""
〜単位元の一覧について〜
最小値:float("inf")
最大値:-float("inf")
XOR:0
区間和:0
区間積:1
最大公約数:0
"""
ide_ele = 0 # 初期値(単位元)の設定
class SegTree:
def __init__(self, segfunc, init_val, ide_ele):
self.segfunc = segfunc
self.ide_ele = ide_ele
self.num = 2 ** n.bit_length()
self.seg = [self.ide_ele] * 2 * self.num
for i in range(n):
self.seg[i+self.num - 1] = init_val[i]
for i in range(self.num - 2, -1, -1):
self.seg[i] = self.segfunc(self.seg[2 * i + 1], self.seg[2 * i + 2])
def update(self, k, x):
k += self.num - 1
self.seg[k] = self.segfunc(self.seg[k], x)
while k:
k = (k - 1) // 2
self.seg[k] = self.segfunc(self.seg[k * 2 + 1], self.seg[k * 2 + 2])
def query(self, l, r):
" l は0index, r は1index"
if r <= l:
return self.ide_ele
l += self.num - 1
r += self.num - 2
res = self.ide_ele
while r - l > 1:
if l & 1 == 0:
res = self.segfunc(res, self.seg[l])
if r & 1 == 1:
res = self.segfunc(res, self.seg[r])
r -= 1
l = l // 2
r = (r - 1) // 2
if l == r:
res = self.segfunc(res, self.seg[l])
else:
res = self.segfunc(res, self.segfunc(self.seg[l], self.seg[r]))
return res
n, q = map(int,input().split()) # 配列の長さ・クエリ数
a = list(map(int,input().split())) # 配列
seg = SegTree(segfunc, a, ide_ele) # オブジェクトの作成