CodeForces 1325D - Ehab the Xorcist【构造+思维】
题意:
给出两个数 \(u,v\),求出一个元素个数最少的集合使得所有数的异或和为 \(u\),和为 \(v\)。并输出元素个数和各个元素。
数据范围:\(0\leq u,v \leq 10^{18}\)
分析:
先分类讨论:
1.当 \(u>v\) 时,显然无解;
2.当 \(u=v\) 且 \(u!=0\) 时,解为 \(u\);
3.当 \(u=v\) 且 \(u=0\) 时,解为空;
4.当 \(u<v\) 时,
根据异或的性质,两个相同数异或结果肯定为 \(0\)。
那么 \(v\) 可以表示为 \(v=u+\frac{(v-u)}{2}+\frac{(v-u)}{2}\);
但当 \(v-u\) 为奇数时,不能满足,无解;
当 \(v-u\) 为偶数时,显然为一个可行解。但因为要求最小,所以要判断元素个数为 \(2\) 时,是否有解。
根据异或的性质: \(a+b=a \bigoplus b+2*(a\& b)\)
即 加法=不进位加法+进位数字
令 \(x=\frac{(v-u)}{2}\)
有 \(v=u+2*x\),所以 \(x=(a\&b),u=a \bigoplus b\)。
当 \(x\) 的第 \(i\) 位为 \(1\) 时,那么 \(a,b\) 的第 \(i\) 位必然为 \(1\),\(u\) 的第 \(i\) 为必然为 \(0\),所以 \(x\&u=0\)。
那么 \(v=u+x+x=(u+x)+x,(u+x)\bigoplus x=u\)。
此时有 \(2\) 个解。如不满足\((x\&u)=0\),则有 \(3\) 个解。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll u,v;
int main()
{
scanf("%lld%lld",&u,&v);
if(u>v||((v-u)&1))
printf("-1\n");
else if(u==v&&u==0)
printf("0\n");
else if(u==v&&u!=0)
printf("1\n%lld\n",u);
else
{
ll x=(v-u)/2;
if((x&u)==0)
printf("2\n%lld %lld\n",u+x,x);
else
printf("3\n%lld %lld %lld\n",u,x,x);
}
return 0;
}