异或运用
a ^ b = c c ^ b = a a ^ a = 0 a ^ a ^ a = a
题目:
给你两个整数n和m,求序列n⊕0,n⊕1,…,n⊕m的MEX。这里,⊕是位XOR运算符。
非负整数序列的MEX是不出现在这个序列中的最小的非负整数。例如,MEX(0,1,2,4)=3,而MEX(1,2021)=0。
输入
第一行包含一个整数t(1≤t≤30000)–测试案例的数量。
每个测试案例的第一行也是唯一一行包含两个整数n和m(0≤n,m≤109)。
输出
对于每个测试案例,打印一个单一的整数–问题的答案。
思路 : 假设答案为x
说明 n ^ (y) = x 那么 y > m n ^ x = y > m 只需要找到 x的最小值
只需要解 n ^ x >= m + 1 求出x的最小值
如果当前 n的第i位为0 (m + 1) 的第i位也为0 那么当前位填0就行
如果当前 n的第i位为1 (m + 1) 的第i位也为1 那么当前位填0就行
如果当前 n的第i位为1 (m + 1) 的第i位 为0 那么当前位填0就行 已经能保证 >= m + 1了 以后直接填0
如果当前 n的第i位为0 (m + 1) 的第i位 为1 那么当前位填1就行 保证接近(m + 1)
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <unordered_map>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5 + 10;
typedef pair <int, int> PII;
int main()
{
int t ;
scanf("%d", &t);
while(t --)
{
ll n , m;
scanf("%lld %lld", &n, &m);
ll ans = 0;
m += 1;
bool flog = false;
for(int i = 31 ; i >= 0 ; i --)
{
int t = n >> i & 1;
int tt = (m) >> i & 1;
if(flog)
{
ans = ans * 2 + 0;
}
else
{
if(t == tt)
ans = ans * 2 + 0;
else if(t == 0 && tt == 1)
ans = ans * 2 + 1;
else if(t == 1 && tt == 0)
{
ans = ans * 2 + 0;
flog = true;
}
}
}
printf("%lld\n", ans);
}
return 0;
}