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

猜你喜欢

转载自www.cnblogs.com/1024-xzx/p/12505710.html