CF1934D1
容易发现若某一位要从 1 变成 0 可以直接变,难点在于 0 变成 1 时前提条件的处理。
1.要求异或上的数不大于原数,所以在原数的更高位中应当存在 1 且不在本次操作中发生改变。
2.要求结果不大于原数,所以在本次操作中更高位应当发生从 1 变成 0 的改变。
所以对于每一个需要从 0 变成 1 的位,更高位中必须存在至少两个 1,且存在需要变成 0 的 1。
然后找出最靠前的需要变成 0 的 1,然后将后面所有的 0 变成 1 都和这个合起来作为第一次操作。因为合法所以原数中必然还存在另一个 1。
然后只需要将其余所有要变成 0 的 1 合起来作为第二次操作即可完成。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void slv(){
ll a,b;
scanf("%lld %lld",&a,&b);
int c10=0,c1=0;
ll hb=-1;
for(ll i=60;i>=0;i--){
if((a&(1LL<<i))){
c1++;
}
if((a&(1LL<<i))&&!(b&(1LL<<i))){
c10++;
if(hb==-1){
hb=(1LL<<i);
}
}
if(!(a&(1LL<<i))&&(b&(1LL<<i))){
if(!(c1>=2&&c10)){
puts("-1");
return ;
}
}
}
vector<ll>ans;
ans.push_back(a);
ll xval=hb;
for(ll i=60;i>=0;i--){
if(!(a&(1LL<<i))&&(b&(1LL<<i))){
xval^=(1LL<<i);
}
}
a^=xval;
ans.push_back(a);
if(a!=b){
ans.push_back(b);
}
printf("%d\n",(int)ans.size()-1);
for(auto x:ans){
printf("%lld ",x);
}
putchar('\n');
}
int main(){
int T=1;
scanf("%d",&T);
while(T--)slv();
return 0;
}

浙公网安备 33010602011771号