最长异或路径

GitHub跳转原题关系图返回列表

把树上路径异或转为两个根前缀异或,再用 01-Trie 求最大异或对。

OJ: luogu

题目 ID: P4551

难度:普及+/提高

标签:01-Trie异或python

日期: 2026-07-16 19:57

题意

求带权树上任意两点间路径边权异或和的最大值。

思路

xor_from_root[u] 为根到 u 的边权异或。两点路径的公共部分异或两次被抵消,因此:

text
xor_path(u, v) = xor_from_root[u] ^ xor_from_root[v]

问题变为在所有根前缀异或值中找最大异或对。逐个扫描值,在 01-Trie 中优先走与当前位相反的儿子,查询它与此前值能得到的最大异或,然后插入当前值。

Python 知识

  • 显式栈遍历树,避免递归深度限制。
  • 算出根异或后 del graph,在创建最多约 310 万个 Trie 节点前释放邻接表。
  • array("I") 保存无符号异或值,两个 array("i") 保存 Trie 儿子。
  • 条件表达式选择当前位对应的儿子数组。

代码

python
import sys
from array import array


input = sys.stdin.buffer.readline
n = int(input())
graph = [[] for _ in range(n)]
for _ in range(n - 1):
    u, v, weight = map(int, input().split())
    u -= 1
    v -= 1
    graph[u].append((v, weight))
    graph[v].append((u, weight))

xor_from_root = array("I", [0]) * n
stack = [(0, -1)]
while stack:
    node, parent = stack.pop()
    for neighbor, weight in graph[node]:
        if neighbor != parent:
            xor_from_root[neighbor] = xor_from_root[node] ^ weight
            stack.append((neighbor, node))
del graph, stack

child_zero = array("i", [0])
child_one = array("i", [0])


def insert(value):
    node = 0
    for bit in range(30, -1, -1):
        children = child_one if value >> bit & 1 else child_zero
        if not children[node]:
            children[node] = len(child_zero)
            child_zero.append(0)
            child_one.append(0)
        node = children[node]


def maximum_xor(value):
    node = answer = 0
    for bit in range(30, -1, -1):
        wanted = child_zero if value >> bit & 1 else child_one
        other = child_one if value >> bit & 1 else child_zero
        if wanted[node]:
            answer |= 1 << bit
            node = wanted[node]
        else:
            node = other[node]
    return answer


insert(0)
answer = 0
for value in xor_from_root[1:]:
    answer = max(answer, maximum_xor(value))
    insert(value)
print(answer)

复杂度

树遍历 O(n)O(n),每个值处理 31 位,总时间 O(31n)O(31n),空间 O(31n)O(31n)

总结

树上异或题先尝试定义根前缀值;路径问题常会立刻化成普通数组上的异或配对。