CodeForces 1325D

题意:

给出两个数 (u,v),求出一个元素个数最少的集合使得所有数的异或和为 (u),和为 (v)。并输出元素个数和各个元素。
数据范围:(0leq 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 igoplus b+2*(a& b))
加法=不进位加法+进位数字
(x=frac{(v-u)}{2})
(v=u+2*x),所以 (x=(a&b),u=a igoplus b)
(x) 的第 (i) 位为 (1) 时,那么 (a,b) 的第 (i) 位必然为 (1)(u) 的第 (i) 为必然为 (0),所以 (x&u=0)
那么 (v=u+x+x=(u+x)+x,(u+x)igoplus 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
");
    else if(u==v&&u==0)
        printf("0
");
    else if(u==v&&u!=0)
        printf("1
%lld
",u);
    else
    {
        ll x=(v-u)/2;
        if((x&u)==0)
            printf("2
%lld %lld
",u+x,x);
        else
            printf("3
%lld %lld %lld
",u,x,x);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/1024-xzx/p/12505710.html