首先这个题就是要求‘异或和‘,不是’和‘
思维:
这就是一个没有加路径优化的并查集,不了解并查集的朋友应该点击上方,去了解一下并查集。
三个数组
1,以我为根点权和,存放以我为根节点的点权和
2,自我权值,存放自己的权值
3,指父数组,用于指向父亲
两个操作
1,查询操作,直接输出以我为根点权和
2,改值操作,先将旧值沿着’指父数组‘都再进行一次异或,因为对同一个数异或两次等于没异或这个数,再将新值沿着’指父数组进行异或‘,此间更新’以我为根点权和‘
代码实现
我还没有找到可以测试的网站进行测试,但是该题m最大10^5 ,我的做法的查值操作的时间复杂度O(1) ,改值操作时间复杂度 O(n),所以我估计可以
n, m = map(int, input().split())
arr = [0] + [int(i) for i in input().split()] # 最终为树内点权和
crr = arr.copy() # 最终为单节点权值
dp = [i for i in range(n + 1)]
def dfs(i, x):
global dp, arr
arr[i] ^= x
if i == dp[i]:
return
dfs(dp[i], x)
for _ in range(n - 1):
a, b = map(int, input().split())
if a > b: # 始终a<b
a, b = b, a
dp[b] = a
dfs(a, arr[b])
for _ in range(m):
br = list(map(int, input().split()))
if br[0] == 1:
dfs(br[1], crr[br[1]]) # 再次异或旧值
crr[br[1]] = br[2]
dfs(br[1], crr[br[1]])# 异或新值
else:
print(arr[br[1]])