C. Serval 和公式
题目
C. Serval 和公式
时间限制:每个测试用例 2 秒
内存限制:每个测试用例 256 兆字节
给定两个正整数 x 和 y(1≤x,y≤10⁹)。
找到一个非负整数 k≤10¹⁸,使得 (x+k)+(y+k)=(x+k)⊕(y+k) 成立∗,或者判断这样的整数不存在。
∗⊕表示按位异或运算。
输入每个测试包含多个测试用例。第一行包含测试用例的数量 t(1≤t≤10⁴)。接下来是测试用例的描述。
每个测试用例的唯一一行包含两个整数 x 和 y(1≤x,y≤10⁹)—— 给定的整数。
输出对于每个测试用例,输出找到的整数 k(0≤k≤10¹⁸)。如果不可能找到这样的整数,输出−1。
如果有多个答案,你可以输出任意一个。
思路
做这个题之前有一个结论需要知道:

结论推导
a+b如果不考虑进位的话,那么对应位置1+1=0,1+0=1,0+1=1,0+0=0,这和异或的运算是一样的,因此a+b减去进位就是a^b;而a+b的进位表示为(a&b)<<1也就是(a&b)*2;
根据题目要求可知这里的a是x+k,b是y+k,只有当(x+k)&(y+k)=0时才会满足条件
两数相与为0,也就是说两数二进制表示下的1不在同一个位置,我们可以想到如果a的二进制表示下是:10000......这种开头是1,后面全是0的情况,那么b的第一个1只要在a的唯一一个1后面,那么就能保证与完为0,那么那个是a,哪个是b呢,很简单,max(x,y)+k是a,min(x,y)+k是b,(特殊的,x如果等于y那么(x+k)&(y+k)=0永远也不会成立)
此时观察题目条件,(1≤x,y≤10⁹),因此max(x,y)+k>1e9且a的二进制表示下是:10000......这种开头是1,后面全是0的情况,那么就ok了,可以令max(x,y)+k=1LL<<50,此时满足所有条件,因此k=(1LL<<50)-max(x,y),直接输出即可
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 5;
void solve() {int x,y;cin >> x >> y;if (x==y) {cout << -1 << endl;return ;}int ans=1LL<<50;cout << ans-max(x,y) << endl;
}
signed main() {int q=1;cin >> q;while (q--) {solve();}
}
