[Luogu] P4551 最长异或路径

\(Link\)

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\)的性质,发现这样做是对的。最后再维护最大值即可。

posted @ 2020-10-22 22:17  andysj  阅读(76)  评论(0编辑  收藏  举报