Problem Description
You are given two positive integers X and K. Return the K-th smallest positive integer Y, for which the following equation holds: X + Y =X | Y
Where '|' denotes the bitwise OR operator.
Where '|' denotes the bitwise OR operator.
Input
The first line of the input contains an integer T (T <= 100) which means the number of test cases.
For each case, there are two integers X and K (1 <= X, K <= 2000000000) in one line.
For each case, there are two integers X and K (1 <= X, K <= 2000000000) in one line.
Output
For each case, output one line containing the number Y.
Sample Input
3
5 1
5 5
2000000000 2000000000
Sample Output
2
18
16383165351936
题目大意:X + Y =X | Y。给出X和一个数K,问能使该式成立的第k小的Y是多少。
题目分析:要想使上式成立,X和Y必须没有交集。所以,此问题其实是求X的补集中第K小的子集是多少。
代码如下:
# include<iostream>
# include<cstdio>
# include<cmath>
# include<string>
# include<vector>
# include<list>
# include<set>
# include<map>
# include<queue>
# include<cstring>
# include<algorithm>
using namespace std;
# define LL long long
# define REP(i,s,n) for(int i=s;i<n;++i)
# define CL(a,b) memset(a,b,sizeof(a))
# define CLL(a,b,n) fill(a,a+n,b)
const double inf=1e30;
const int INF=1<<30;
const int N=1000;
unsigned long long n,k;
const unsigned long long a=0xffffffffffffffff;
unsigned long long ans;
void dfs(unsigned x)
{
if(x<=0) return ;
int t=x;
int base=0;
while(t){
t/=2;
++base;
}
unsigned long long p=1;
int id;
for(int cnt=0,i=0;i<64&&cnt<=base;++i){
id=i;
if(n&(p<<i)){
++cnt;
if(cnt==base) ans|=(p<<i);
}
}
dfs(x-(p<<(base-1)));
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
cin>>n>>k;
n=~n;
ans=0;
dfs(k);
cout<<ans<<endl;
}
return 0;
}