解题思路
要求 p⊕(p+1)⊕⋯⊕q=w 且 q 最小、q≥p。直接从 p 往后扫最多约 106 步也能过,但用前缀异或可以 O(1) 判定。
- 记 xor_pref(n)=0⊕1⊕⋯⊕n,空前缀 xor_pref(−1)=0。则区间异或就是 xor_pref(q)⊕xor_pref(p−1)。
- 0 到 n 的连续异或每 4 个数一循环:若 nmod4=0 结果是 n;等于 1 结果是 1;等于 2 结果是 n+1;等于 3 结果是 0。
- 令 need=w⊕xor_pref(p−1),问题变成:最小的 q≥p 满足 xor_pref(q)=need。
- 前缀异或只能取到四类值:0、1、模 4 余 0 的数、模 4 余 3 的数。因此:
- need=0:取 q=0(仅当 p=0)或最小的 q≥p 且 qmod4=3;
题目内容
边缘节点每天要处理一串按序号递增的数据帧。运维规定:从某个起始序号 p 开始,把若干个连续序号做按位异或,折叠结果必须刚好等于一份事先下发的校验字 w。
也就是要找到一个右端点 q,使得
p⊕(p+1)⊕⋯⊕q=w
并且 p≤q。符号 ⊕ 表示按位异或。
右端点可以一直往后延,但不允许跳号、也不允许小于 p。若存在多个合法 q,只保留最小的那个;若无论怎样延长都凑不出 w,视为无法对齐。
输入描述
第一行一个整数 w,表示目标校验字。(0≤w<1048576)
第二行一个整数 p,表示起始序号。(0≤p<1048576)
输出描述
若能对齐,输出最小的右端点 q;否则输出 −1。
样例1
输入
1
2
输出
3
说明
- 2⊕3=1,已经等于校验字。
- 只取 2 时结果是 2,对不齐,所以最小右端是 3。
样例2
输入
2
5
输出
-1
说明
从 5 起无论把右端拉到哪里,连续异或都到不了 2,因此输出 −1。