给一个无向图,含边权,并定义这样一种三元组(u, v, t)满足:从u到v有一条路径且路径上的边权异或和为t。求所有三元组的t的和
我们对它逐步拆解分析,先考虑最简单的情况——如果这个图是一棵树。首先我们发现由于异或的特殊性,经过相同的边两次等价于没有经过,所以对于所有的点对(u, v)它有唯一的异或和dis(u, v) 且等于dis(u, root) ^ dis(v, root),因为路径上重合的部分被异或掉了。这样的关系给了我们一个启示:可以一次计算出所有点到根的异或和(用dfs)。然后再用它来求两点间的异或和。
接下来我们向图中加入环,我们知道如果在一条边上“往返”,是对结果无影响的,所以对于该图中所有的环(重边也算),都可以随意地向(u, v)的基本路径中添加。相当于存在这样一个集合B,集合中是每个环完整一圈的异或和,我们可以从这个集合中任意取数并异或上1中的结果。
因此我们可以去计算集合B的线性基。
进而我们需要考虑的是如何计算,由于点和边的数量级是1e5,如果遍历点对会超时,这个时候就需要找规律。最终是求和,我们按照二进制位去累加各种情况的贡献,对于第i位,去计数有多少点的深度值dep[i] = dis(i, root)在这一位上是1或0,分别是tot0和tot1,如果不考虑环,贡献值为tot0tot1\2^i。即最终有tot0*tot1对点的距离值的第i位是1,那就把它们加在一起。考虑环的话则,如果该位原本没有1,可以通过B的线性基来补充。具体公式在代码中。这样计算的复杂度是O(62*m)。
对于多个联通块,每发现一个联通块就单独计算它的贡献并累加。需即使清除记录的上个联通块的环。
1 |
|