Codeforces Round #628 (Div. 2)] D-Ehab the Xorcist
题意:
给定两个整数\(u,v(0 \le u,v \le 10^{18})\)
让你构造一个长度\(\mathit n\)最小的数组\(arr\),使其:
1、\(arr_1 \oplus arr_2 \oplus \dots \oplus arr_n=u\)
2、\(\sum_{i=1}^n arr_i= v\)
不存在这个数组就输出“-1”。
思路:
先考虑不存在的情况:
1、当\(u>v\)时,一定不存在,因为异或是不进位的加法,不可能一群数异或起来比加起来还大。
2、\(u,v\)奇偶性不一样,考虑异或运算和加法运算的对最低位的影响是相同的(因为没有位置给最低位进位)。
然后都是存在解的情况:
也是分情况讨论:
1、当\(u=v\),如果\(u=0\),那么空数组就可以满足条件,否则构造一个\(n=1,arr_1=v\)的数组即可。
2、令\(c=v-u\),即异或运算不进位时的损失值,
如果\(c,u\)的二进制与等于0,那么答案为:
\(n=2,arr_1=x + c / 2,arr_2=c / 2\)
否则答案为:
\(n=3,arr_1=x ,arr_2=c / 2,arr_3=c / 2\)
代码:
int main()
{
//freopen("D:\\code\\text\\input.txt","r",stdin);
//freopen("D:\\code\\text\\output.txt","w",stdout);
ll x, y;
while (~scanf("%lld %lld", &x, &y))
{
if (x > y)
{
printf("-1\n");
} else
{
if (x == y) {
if (x == 0)
printf("0\n");
else
{
printf("1\n");
printf("%lld\n", x);
}
} else {
ll c = y - x;
if (c & 1)
{
printf("-1\n");
} else
{
ll z = c / 2;
if ((z & x) == 0)
{
printf("2\n");
printf("%lld %lld\n", x + c / 2, c / 2 );
} else
{
printf("3\n");
printf("%lld %lld %lld\n", x, c / 2, c / 2 );
}
}
}
}
}
return 0;
}