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;
}