给定一棵包含 个顶点的带边权树,顶点编号从 到 。对于每个满足 的 ,顶点 与其父顶点 ()相连,边权为 ()。请注意,顶点 没有父节点,为了方便起见,我们设 。
Sasaki 在树上移动的唯一方式是通过传送。Sasaki 可以透过 个能量从顶点 传送到顶点 当且仅当同时满足以下所有条件:
- 是 的祖先,或者 是 的祖先,并且
- 从 到 路径上所有边权的按位异或和(XOR)不超过 。
注意:每次的传送不消耗能量;每次的传送后,Sasaki 还是有 个能量
::::info[什么时候 是 的祖先?]{open}
如果以下至少一个条件为真,则顶点 是顶点 的祖先:
- 顶点 就是顶点 (),或者
- 顶点 是顶点 的父节点(),或者
- 顶点 是顶点 的父节点的父节点(),或者
- 顶点 是顶点 的父节点的父节点的父节点(),或者
- 依此类推。
::::
::::info[什么是按位异或和(XOR)?]{open}
两个非负整数 和 的按位异或和(记为 )定义如下:
- 当 写为二进制时,如果 和 在 位的数字恰好有一个为 ,则该位的结果为 ,否则为 。
例如:
多个整数 的按位异或定义为 。
注意 是满足交换律和结合律的运算符。也就是说, 和 。因此,以何种顺序排列这些整数或者以何种顺序进行异或运算并不影响最终的结果。
::::
Miyako 需要回答 个询问。每个询问由一对整数 和 指定。Miyako 的任务是计算 Sasaki 使用零次或多次传送操作从顶点 到达顶点 所需的 最小能量。
实现详情
你需要实现以下函数:
void init(int N, std::vector<int> P, std::vector<int> W)
- :树的顶点数量。
- :长度为 的整数数组,分别指定每个顶点的父节点和连接它们的边权。
- 此函数在开始时(在调用任何
minimum_energy 之前)恰好被调用一次。
int minimum_energy(int U, int V)
- :描述一次询问的一对整数。
- 此函数在调用
init 后恰好被调用 次。
- 此函数应返回给定询问的答案。