看到异或求和,考虑拆位计算 $v+d(c,x)$ 的第 $k$ 位。不难发现它随着 $d(c,x)$ 每增大 $2^k$ 改变一次。
这启示我们对于每个点考察它对所有祖先的贡献。于是我们要做的第一步是树上差分,将一系列深度相差 $2^k$ 的祖先的差分值异或 $1$。
这个操作不能暴力做。考虑用一个桶对于每个 $i$ 记录某个点的所有祖先中,深度 $\bmod2^k=i$ 的点的差分值。但是这样子树需要向父亲贡献一个合并复杂度为 $O(s)$($s$ 表示子树大小)或 $O(2^k)$ 的信息,取决于考虑子树内每个点对桶的贡献,还是直接使用子树的桶在对应位置相加。前者可以用树上启发式合并优化。
更好的做法是维护子树内可减信息的经典 trick(天天爱跑步):
维护一个全局桶,子树跟处只需要记录自己关心的某个位置的值,在遍历子树前和遍历子树后的差,即可求得子树内对桶该位置的贡献。