Codeforces 1325 D. Ehab the Xorcist (异或)

题目链接

题目大意

给出一个 u 和一个 v ,要求构造出最短的一个数组,使得所有元素异或的结果为 u,所有元素之和的结果为 v。

注意输入为 long long

题目思路

看到此题我一点思路都没有

最近写题目感觉有一个规律,如果数据开到long long那么基本都是分类讨论

因为元素范围多,所以时间复杂度,我觉得基本都是o(1)o(log(n))的复杂度我还没见过

正题

首先先了解一个知识点:异或可以考虑为不进位的加法

我认为此题最关键的就是要明白数组元素最多3个。

如果可以划分。显然可以分为 (v-u)/2,(v-u)/2,u。显然可以得出这三个元素满足题目条件。

然后分类即可

1:当 u 和 v 都为 0 时,答案为 0

2:当 u=v时,答案为 u 或者 v

3:由于异或是不进位的加法,所以u一定要小于等于v,所以当 u>v 时,答案为 −1

4:两个相同的数异或值肯定为 0 , 0 异或任何数又是那个数的本身,所以我们设 a=(v−u)/2 然后输出 a,a,u肯定符合。

5:如果 (v−u)%2!=0 那么肯定是 −1。

6:还有一种长度为 2 的情况,若有(a^u)=(a+u),则可将前两项进行合并,这个点最难。输出。

注意:和 ^ 这个符号有关最好打个括号,他的优先级比较玄学,其实就是比较低

代码

#include<cstdio>
using namespace std;
typedef long long ll;
ll u,v,n;
int main(){
    scanf("%lld %lld",&u,&v);
    if(u>v||(v-u)%2==1){
        n=-1;
    }else if(u==0&&v==0){
        n=0;
    }else if(u==v){
        n=1;
    }else if((u^((v-u)/2))==(v+u)/2){//判断是否可以合并,注意其优先级
        n=2;
    }else{//分为(v-u)/2,(v-u)/2,(v+u)/2
        n=3;
    }
    printf("%lld\n",n);
    if(n==1){
        printf("%lld\n",u);
    }else if(n==2){
        printf("%lld %lld\n",(v-u)/2,(u+v)/2);
    }else if(n==3){
        printf("%lld %lld %lld\n",(v-u)/2,(v-u)/2,u);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值