1 条题解

  • 0
    @ 2026-8-20 2:00:09

    题解

    思路

    先考虑一段边权序列。固定某一二进制位,把序列的前缀异或值写出,并包含空前缀。一个连续子段在该位为 11,当且仅当它两端的两个前缀异或值不同。若前缀异或中有 c0c_000c1c_111,这一位对答案的贡献就是 c0c1c_0c_1 乘该位权值。

    做法

    为一个序列段维护长度、总异或,以及每一位上前缀异或为 0/10/1 的个数。合并左右两段时,左段前缀全部保留;右段的非空前缀先与左段总异或相异或后加入。空前缀不能重复计算。这个合并满足结合律。

    反转序列时,反转后的前缀对应原序列的后缀。每个后缀异或等于整段异或再异或某个原前缀,因此只需根据整段异或交换相应位的 0/10/1 计数。

    对树进行重链剖分,把每条边的权值存到较深端点的 DFS 序位置,并在线段树中维护上述序列量。查询路径时,从两端向最近公共祖先跳重链:从 uu 侧取出的区间需要反转后追加,从 vv 侧取出的区间按正向前置。最后合并两侧,逐位计算 c0c12bc_0c_1 2^b。修改一条边就是修改其较深端点的位置。

    证明

    任意子路径的边权异或等于两个前缀异或的异或,所以固定二进制位时,贡献为 11 的子路径恰与一对取值不同的前缀一一对应,共有 c0c1c_0c_1 个。

    序列合并公式枚举了左段的全部前缀,以及跨过整个左段后进入右段的全部非空前缀,二者无重无漏。反转公式由“后缀异或等于总异或再异或前缀”直接得到。因此维护量能按任意分段顺序还原真实路径序列。

    重链剖分取出的区间按路径方向反转或前置后,其合并结果与从 uuvv 的边权顺序完全一致。于是最终逐位贡献之和就是所有子路径异或值之和。单点修改后线段树重新合并所有受影响区间,后续查询仍正确。

    复杂度

    每个维护量只有 1010 个二进制位。预处理 O(n)O(n),修改 O(10logn)O(10\log n),查询 O(10log2n)O(10\log^2n),空间 O(10n)O(10n)

    • 1

    信息

    ID
    902
    时间
    3000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    0
    上传者