传送门:https://codeforces.ml/contest/1325/problem/D
题意:给你两个整数u和v,需要你构造一个最短的序列,使他们的异或和是u,和是v,输出序列长度和序列的每个数,若构造不出来输出-1。
思路:当u>v的时候显然没有解,因为u对应的二进制位已经比v大了。
当u==v时,输出一个u就行。
那么当u<v时就是我们要讨论的情况了,对于最一般的情况,我们令x=(v-u)/2,我们可以构造出u,x,x这个序列一定符合题意,所以最长长度为三,但有一种特殊情况,就是a^b==u,a+b==v,我们知道异或就是不进位加法,而a+b也可以写成a^b+2(a&b),也就是加法=不进位加法+进位数字,带入我们参数我们就可以得到a&b=(v-u)/2,惊不惊喜意不意外,我们设为x,我们看x的二进制位,若x二进制位上有1,则a和b该位上一定是1,那么他们的异或u该位就是0,x二进制上为0时没有限制。所以我们可以得出,当x位上有1,但u上也是1->(x&u!=0)则不满足此特殊情况,可以输出一般情况的解了。当满足的时候,代表x&u==0,也就是x^u==x+u,所以我们可以构造出u+x,x这个序列,长度为2且符合题意!
ac代码:
#include<iostream> using namespace std; typedef long long ll; ll u,v; int main() { cin>>u>>v; if(u>v) return cout<<-1,0; if(u==0&&v==0) return cout<<0,0; if(u==v) return cout<<1<<' '<<u,0; ll x=(v-u)/2; if((v-u)&1) return cout<<-1,0; if((x&u)==0){ cout<<2<<' '<<u+x<<" "<<x; return 0; } cout<<3<<' '; cout<<u<<" "<<x<<" "<<x; return 0; }