Description
给出一棵树,权值未知,但是给出每条边两个端点权值的异或值,求原来的权值。
Solution
假设权值
,那么从它开始进行一遍
赋值可以得到所有点当前的权值
。当然
不一定等于
,假设
,那么真实的
。
现在给出每个
的范围满足
,即
,设
,等式两边异或上
得到
,于是
满足
。
于是现在转化成考虑以下问题:
给出
个限制条件,求出它们之间的交集。(转换成求被覆盖
次的线段长度)
对于每个能够取到符合条件的数字。我们可以用线段差分表示,例如
区间如果满足某个限制条件,那么标记
,
, 这样在遍历
区间的时候得到的权值都是
,到了
这个点就变成
。那么
个条件都满足,只需要找到哪些点权值为
,直接找出所有符合条件的线段长度即可。
如何打标记?
直接做 不方便,不妨拆成
,对于第一个区间
,符合条件打上
标签,
打上
标签,最终
上标签都是
,符合我们的期望。
- 关于如何找到可行的区间?
考虑单独一对 的操作,当搜索
时,对
搜索二进制上的每一位,情况无非就是
四种情况,我们规定第一个二进制位表示
,第二个二进制位表示
,在保证从高位到低位的情况下,维护当前前缀
。
- 当出现
时,因为
当前位为
,所以对于可选方案可以取
,当取
时,类似于数位
,当前不受
限制,后面的数字已经可以随便取了,而当前位异或值为
, 我们可以考虑该位为
的所有数字,于是将这一
的所有数字
加入,当取
的时候,该位为
,
不变,
下一层。
- 当出现
时,因为当前位为
,可以取
,同理,取
的时候解除
限制,后面二进制位可以任取搭配,当前位异或值为
,所以可以加入
,如果取
的话,异或值为
,于是
,
下一层。
- 当出现
时,因为当前位为
,任何数字都无法取到,但是异或值为
,此时
,
下一层。
- 当出现
时,因为当前位为
,任何数字都无法取到,异或值为
,此时
不变,
下一层。
Code
https://ac.nowcoder.com/acm/contest/view-submission?submissionId=48324656