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;
}
posted @ 2024-07-22 18:05  ax_by_c  阅读(8)  评论(0)    收藏  举报