I:异或和 (第十四届蓝桥杯省赛)

点击此处了解更多

首先这个题就是要求‘异或和‘,不是’和‘

思维:

这就是一个没有加路径优化的并查集,不了解并查集的朋友应该点击上方,去了解一下并查集。

三个数组

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]])

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

自 在

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值