1 条题解
-
0
题解
思路
先考虑一段边权序列。固定某一二进制位,把序列的前缀异或值写出,并包含空前缀。一个连续子段在该位为 ,当且仅当它两端的两个前缀异或值不同。若前缀异或中有 个 和 个 ,这一位对答案的贡献就是 乘该位权值。
做法
为一个序列段维护长度、总异或,以及每一位上前缀异或为 的个数。合并左右两段时,左段前缀全部保留;右段的非空前缀先与左段总异或相异或后加入。空前缀不能重复计算。这个合并满足结合律。
反转序列时,反转后的前缀对应原序列的后缀。每个后缀异或等于整段异或再异或某个原前缀,因此只需根据整段异或交换相应位的 计数。
对树进行重链剖分,把每条边的权值存到较深端点的 DFS 序位置,并在线段树中维护上述序列量。查询路径时,从两端向最近公共祖先跳重链:从 侧取出的区间需要反转后追加,从 侧取出的区间按正向前置。最后合并两侧,逐位计算 。修改一条边就是修改其较深端点的位置。
证明
任意子路径的边权异或等于两个前缀异或的异或,所以固定二进制位时,贡献为 的子路径恰与一对取值不同的前缀一一对应,共有 个。
序列合并公式枚举了左段的全部前缀,以及跨过整个左段后进入右段的全部非空前缀,二者无重无漏。反转公式由“后缀异或等于总异或再异或前缀”直接得到。因此维护量能按任意分段顺序还原真实路径序列。
重链剖分取出的区间按路径方向反转或前置后,其合并结果与从 到 的边权顺序完全一致。于是最终逐位贡献之和就是所有子路径异或值之和。单点修改后线段树重新合并所有受影响区间,后续查询仍正确。
复杂度
每个维护量只有 个二进制位。预处理 ,修改 ,查询 ,空间 。
- 1
信息
- ID
- 902
- 时间
- 3000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 0
- 上传者