给定两个整数n和m,求数列n0, n1,..,n m,这里是位异或运算符。非负整数序列的MEX是这个序列中没有出现的最小的非负整数。例如,MEX(0,1, 2,4) = 3, MEX(1,2021) = 0。输入第一行包含一个整数t (1 < t < 30 000)——测试用例的数量。每个测试用例的第一行也是唯一一行包含两个整数n和m (0<n, m < 10°)。输出对于每个测试用例,打印一个整数——问题的答案。
Example
input
Copy
5 3 5 4 6 3 2 69 696 123456 654321
output
Copy
4 3 0 640 530866
请注意在第一个测试用例中,序列是30,31,3,3,34,35,3,2,1,0,7,6。数列中不存在的最小非负整数,即数列的MEX为4。在第二个测试用例中,序列是40,41,42,43,44,45,4 6,或者4,5,6,7,0,1,2。数列中不存在的最小非负整数,即数列的MEX为3。在第三个测试用例中,序列是30,31,32或3,2,1。数列中不存在的最小非负整数,即数列的MEX为0。
题解:
我们看到异或,应该回想他的一些性质
异或交换律,是本题的关键
a ^ b = c <=> a ^ c = b(很重要的性质)
那么结合到这题
给了我们n ^ 0 = ?,n ^ 1 = ?,n ^ 2 = ?,...... n ^ m = ?找出最大的MEX
我们交换一下就变成了
n ^ ? = 0,n ^ ? = 1,n ^ ? = 2,n ^ ? = 3,... n ^ ? = m
问题就转化为了n ^ 一个值 > m,找到这个最小的值
#include<iostream>
#include<string>
#include<vector>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
void solve()
{
int n,m;
scanf("%d%d",&n,&m);
m++;
int ans = 0;
for(int i = 30;i >= 0;i--)
{
int w = (1 << i);
if(w&m)
{
if((n&w) == 0)
{
ans |= w;
n |= w;
}
}
if(n >= m)
{
printf("%d\n",ans);
break;
}
}
}
signed main()
{
// ios::sync_with_stdio(0);
// cin.tie(0);cout.tie(0);
int t = 1;
scanf("%d",&t);
while (t--)
{
solve();
}
return 0;
}