zoukankan      html  css  js  c++  java
  • 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;
    }
    
    
  • 相关阅读:
    U盘禁用工具1.3
    《中文专业论文写作概论》笔记
    基于WAP1.0的手机论坛网站系统
    销售统计SQL
    移动如何保护个人开发者的合法权益?
    c#使用winnet检测网络连接状况
    HBASE客户端的一些参数设置
    代理模式
    使用Eclipse+Axis2生成webservice
    java多线程的理解
  • 原文地址:https://www.cnblogs.com/1024-xzx/p/12505710.html
Copyright © 2011-2022 走看看