[Luogu] P4551 最长异或路径
Description
给定一棵\(n\)个点的带权树,求最长的异或路径。(\(1 \leq n \leq 100000 ;0 \leq w<2^{31}\))
异或路径指的是指两个结点之间唯一路径上的所有边权的异或和。
Solution
设\(dp[x]\)表示根节点到\(x\)的路径上所有边权的\(xor\)和。先预处理求出所有的\(dp[x]\)。
这里有一个重要的性质:树上\(x\)到\(y\)的路径上所有边权的\(xor\)和的结果就等于\(dp[x]\ xor\ dp[y]\)(\(a\ xor\ a = 0\),\(x\)到根和\(y\)的根着两条路径重叠的部分恰好抵消)
所以问题转化为从\(dp[1]\)到\(dp[n]\)中选出两个,使它们\(xor\)的结果最大。这时就可以用到\(Trie\)树来解决了。
我们可以把每个整数看做长度为\(32\)的二进制\(01\)串。对于某一位\(a_i\),我们把它之前的\(a_j(j<i)\)对应的二进制串插入\(Trie\)树。接下来,对于\(a_i\)对应的二进制串,我们在\(Trie\)中进行检索操作,每一步都尝试沿着与\(a_i\)当前位相反的字符指针向下访问(位从高位到低位枚举),若指向非空,则当前总和加上\(1<<i\),否则只好访问相同的字符指针。根据\(xor\)运算相同得\(0\),不同得\(1\)的性质,发现这样做是对的。最后再维护最大值即可。