結果
| 問題 |
No.1641 Tree Xor Query
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2021-08-06 21:41:13 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 565 ms / 5,000 ms |
| コード長 | 3,717 bytes |
| コンパイル時間 | 351 ms |
| コンパイル使用メモリ | 81,664 KB |
| 実行使用メモリ | 114,060 KB |
| 最終ジャッジ日時 | 2024-09-17 01:32:17 |
| 合計ジャッジ時間 | 4,108 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 18 |
ソースコード
#HLD
class HeavyLightDecomposition:
def __init__(self, G):
self.G = G
self.n = len(G)
self.par = [-1] * self.n
self.size = [1] * self.n
self.head = [0] * self.n
self.preord = [0] * self.n
self.k = 0
for v in range(self.n):
if self.par[v] == -1:
self.dfs_sz(v)
self.dfs_hld(v)
def dfs_sz(self, v):
G = self.G
stack, order = [v], [v]
while stack:
p = stack.pop()
for u in G[p]:
if self.par[p] == u: continue
self.par[u] = p
stack.append(u)
order.append(u)
while order:
p = order.pop()
ch = G[p]
if len(ch) and ch[0] == self.par[p]:
ch[0], ch[-1] = ch[-1], ch[0]
for i, u in enumerate(ch):
if u == self.par[p]: continue
self.size[p] += self.size[u]
if self.size[u] > self.size[ch[0]]:
ch[i], ch[0] = ch[0], ch[i]
def dfs_hld(self, v):
G = self.G
stack = [v]
while stack:
p = stack.pop()
self.preord[p] = self.k
self.k += 1
top = self.G[p][0]
for u in G[p][::-1]:
if u == self.par[p]: continue
if u == top:
self.head[u] = self.head[p]
else:
self.head[u] = u
stack.append(u)
def enumerate_vertices(self, u, v):
while True:
if self.preord[u] > self.preord[v]: u, v = v, u
l = max(self.preord[self.head[v]], self.preord[u])
r = self.preord[v]
yield l, r
if self.head[u] != self.head[v]:
v = self.par[self.head[v]]
else:
return
def enumerate_edges(self, u, v):
while True:
if self.preord[u] > self.preord[v]: u, v = v, u
if self.head[u] != self.head[v]:
yield self.preord[self.head[v]], self.preord[v]
v = self.par[self.head[v]]
else:
if u != v:
return self.preord[u] + 1, self.preord[v]
def subtree(self, v):
l = self.preord[v]
r = self.preord[v] + self.size[v]
return l, r
def lowest_common_ancestor(self, u, v):
while True:
if self.preord[u] > self.preord[v]: u, v = v, u
if self.head[u] == self.head[v]: return u
v = self.par[self.head[v]]
#BIT
class BinaryIndexedTree():
def __init__(self, n):
self.n = 1 << (n.bit_length())
self.BIT = [0] * (self.n + 1)
def build(self, init_lis):
for i, v in enumerate(init_lis):
self.add(i, v)
def add(self, i, x):
i += 1
while i <= self.n:
self.BIT[i] ^= x
i += i & -i
def sum(self, l, r):
return self._sum(r) ^ self._sum(l)
def _sum(self, i):
res = 0
while i > 0:
res ^= self.BIT[i]
i -= i & -i
return res
n, q = map(int, input().split())
A = list(map(int, input().split()))
G = [[] for i in range(n)]
for _ in range(n - 1):
u, v = map(int, input().split())
G[u - 1].append(v - 1)
G[v - 1].append(u - 1)
HLD = HeavyLightDecomposition(G)
BIT = BinaryIndexedTree(n)
for i, a in enumerate(A):
BIT.add(HLD.preord[i], a)
for _ in range(q):
t, x, y = map(int, input().split())
if t == 1:
BIT.add(HLD.preord[x - 1], y)
else:
l, r = HLD.subtree(x - 1)
ans = BIT.sum(l, r)
print(ans)