1 条题解

  • 0
    @ 2026-4-1 13:21:26

    题意简述

    给定一棵 nn 个节点的树,需要给每条边赋一个 [0,2301][0, 2^{30}-1] 的整数权值。
    qq 条限制:每条限制 (u,v,x)(u, v, x) 表示 uuvv 路径上所有边的权值异或和等于 xx
    要求判断是否存在合法赋值,若存在,输出一种方案,使得所有边权异或和 a1a2an1a_1 \oplus a_2 \oplus \dots \oplus a_{n-1} 最小。


    核心转化

    pip_i 表示从节点 11 到节点 ii 的路径上所有边的异或和。
    对于树上的任意两个节点 u,vu, v,它们的路径异或为:

    xor(u,v)=pupv\text{xor}(u,v) = p_u \oplus p_v

    这是因为从 11lca(u,v)\text{lca}(u,v) 的路径在 pup_upvp_v 中分别出现一次,异或后抵消。

    因此:

    • 每条边 (u,v)(u,v) 的权值可以表示为 auv=pupva_{uv} = p_u \oplus p_v
    • 给边赋权等价于给每个节点(除根外)赋 pip_i

    条件图的建立

    对每条限制 (u,v,x)(u, v, x),我们有:

    pupv=xp_u \oplus p_v = x

    这可以看作在图 GG' 中连一条无向边 (u,v)(u, v),权值为 xx

    uuvvGG' 中连通,则 pvp_v 可由 pup_u 推导出来:

    pv=pu(路径异或)p_v = p_u \oplus (\text{路径异或})

    可行性判断

    GG' 的每个连通分量:

    • 任选一个节点 rr,设 pr=0p_r = 0,通过 BFS/DFS 求出分量内所有 pip_i
    • 对分量内的每条边 (u,v,x)(u, v, x),检查 pupvp_u \oplus p_v 是否等于 xx

    若某条边不满足,则无解。


    最小化目标

    目标:最小化 S=a1a2an1S = a_1 \oplus a_2 \oplus \dots \oplus a_{n-1}

    ai=puipvia_i = p_{u_i} \oplus p_{v_i} 代入:

    $$S = \bigoplus_{\text{edge } (u,v)} (p_u \oplus p_v) $$

    在异或和中,pip_i 出现的次数等于节点 ii 在原树 GG 中的度数 deg(i)\deg(i)
    因此:

    $$S = \bigoplus_{i=1}^n \left( p_i \text{ 如果 } \deg(i) \text{ 是奇数,否则 } 0 \right) $$

    即:

    S=deg(i) oddpiS = \bigoplus_{\deg(i) \text{ odd}} p_i

    自由度的处理

    GG'kk 个连通分量,第 jj 个分量中任选一个代表 rjr_j,则分量内任意节点 iipip_i 可表示为:

    pi=prjdip_i = p_{r_j} \oplus d_i

    其中 did_i 是已知常数(drj=0d_{r_j} = 0)。

    于是:

    $$S = \bigoplus_{j=1}^k \left( p_{r_j} \oplus \left( \bigoplus_{\substack{i \in \text{comp}_j \\ \deg(i) \text{ odd}}} d_i \right) \right) $$

    记:

    $$c_j = \bigoplus_{\substack{i \in \text{comp}_j \\ \deg(i) \text{ odd}}} d_i $$

    则:

    $$S = \bigoplus_{j=1}^k \left( p_{r_j} \oplus c_j \right) $$

    分类讨论

    • cj=0c_j = 0 对所有 jj 成立,则 S=j=1kprjS = \bigoplus_{j=1}^k p_{r_j}

      • k=0k = 0S=0S = 0
      • k>0k > 0,我们可以独立选择 prjp_{r_j} 以最小化 SS
        由于 SSprjp_{r_j} 的异或,最小值为 00,只需让所有 prjp_{r_j} 相等即可(例如全 00)。
    • 若存在 cj0c_j \neq 0,则 S=j(prjcj)S = \bigoplus_{j} (p_{r_j} \oplus c_j)
      LL 为满足 cj0c_j \neq 0jj 集合。
      L|L| 为奇数,则 SS 恒非零,最小值为 jLcj\bigoplus_{j \in L} c_j(可通过适当调整 prjp_{r_j} 实现)。
      L|L| 为偶数,可让 S=0S = 0

    实际操作中,我们固定 pr1=0p_{r_1} = 0,对每个 j>1j > 1jLj \in L 则设 prj=c1cjp_{r_j} = c_1 \oplus c_j 使 SS 最小。


    算法步骤

    1. 读入树 GG,计算每个节点的度数 deg(i)\deg(i)
    2. 建立图 GG':对每个限制 (u,v,x)(u, v, x),在 uuvv 间加无向边权 xx
    3. GG' 的每个连通分量:
      • 任选代表 rr,设 pr=0p_r = 0,BFS 求分量内所有 pip_i
      • 检查分量内边权是否一致。
    4. 若检查失败,输出 "No"
    5. 否则,计算 $c_j = \bigoplus_{\substack{i \in \text{comp}_j \\ \deg(i) \text{ odd}}} d_i$。
    6. 选择 prjp_{r_j} 使 SS 最小。
    7. 根据 pip_i 计算边权 auv=pupva_{uv} = p_u \oplus p_v 并输出。

    复杂度

    • 时间复杂度:O(n+q)O(n + q)(若使用位运算优化,也可 O((n+q)logX)O((n+q)\log X) 通过)
    • 空间复杂度:O(n+q)O(n + q)

    这样,我们就能在满足条件的前提下,最小化所有边权的异或和。

    • 1

    信息

    ID
    6190
    时间
    1000ms
    内存
    256MiB
    难度
    2
    标签
    递交数
    1
    已通过
    1
    上传者