cf题解

Codeforces 1325D - Ehab the Xorcist

早上看了别人写的博客,研究了好久才研究透,写一点自己的理解
这道题,首先你拿到u,v两个数,根据二进制的关系,你可以知道,异或值不会大于和,只会小于等于和。然后再看奇偶,如果异或值为奇数,那么一定是由奇数个奇数异或得到,才会导致最后一位是1,然后又因为奇数个奇数不管加上多少个偶数都是奇数,所以可以知道,异或值和和的奇偶性是一样的,所以在一开始的时候就可以将奇偶性不同,且u>v的情况都输出-1,然后接着看合理的情况的时候,那么又可以分情况讨论如果u==v和u!=v两种情况,对于第一种情况如果都为零那么就是零,如果不为零,就输出1和u。我们取其中一个答案x为u,我们直到了和是v,那么剩下部分就是y=v-u
那么现在u=u^y,为了使等式成立,那么我们只有把y拆为偶数份相同的部分,这样才能在异或的时候两两相同异或为零,又因为要求长度最短,所以分为两份是最好的,这样我们就能得到y=(v-u)/2,这样u=x ^ y ^ y,又因为如果 u 和 (v-u)/2 的二进制上的 1 不会在同一位同时出现此时异或运算会等同于二进制加法运算,这样u=(x+y) ^ y这样就变成两个数字了,长度更短了,也符合题意了,所以在写的时候,要考虑1是不是都在不同的位置上,

#include
int main()
{
    long long u,v;
    scanf("%lld%lld",&u,&v);
    if(u%2==v%2&&u<=v)
    {
        if(u==v)
        {
            if(u==0)
                printf("0\n");
            else
            {
                printf("1\n");
                printf("%lld\n",u);
            }
        }
        else
        {
            long long int x=u;
            long long int y=(v-u)/2;
            if((x&y)==0)
            {
                printf("2\n%lld %lld\n",x+y,y);
            }
            else
            {
                printf("3\n%lld %lld %lld\n",x,y,y);
            }
        }


    }
    else
        printf("-1\n");
}

你可能感兴趣的:(cf题解)