CF-Round#628-div2-D题

CF-Round#628-div2-D题

D. Ehab the Xorcist

传送门

本题异或构造题。
看到异或我真的怕。。。

这里表示一下加法转化为异或的公式:
a+b=a⊕b+2∗(a&b)
异或其实是不进位的加法。

题目要求让你构造一个序列。让这些序列的和为v,然后异或的值为u。构造的序列长度尽可能小。
我们讨论几种特殊情况。
当u>v的时候不存在这样的序列输出-1
当u=v=0的时候看样例只输出一个0,空序列
当u=v != 0的时候就输出长度为1的u就可以啦
当u<v的时候
我们很容易发现构造的序列长度最小为2,最大为3.
为啥捏,你看。我们直接把u丢进序列中,然后剩余的就是x和x,x = (v-u)/2;
这里还需要再讨论一下,如果v-u不是偶数的话,也输出-1,因为奇数的话加起来就不等于v-u了呀。
所以长度为3的序列[u, x, x]是一定满足要求的。
但是题目要求是求最小的长度。
我们考虑一下长度三能否转换为长度为2
根据这个式子a+b=a⊕b+2∗(a&b)=v
我们可以得到:
a &b=(v−u)/ 2=x
如果x中的某一位为1。那么a和b的那一位必然都为1.因为相与嘛
所以a⊕b=u.所以u的那一位必然为0
如果x和u的同一位均为1.那么就不能满足x&u=0 。那么我们找不到这样的a,b所以一定序列的长度一定为3
如果x中的某一位为0,那么a和b没有特殊要求

如果x &u=0。这就意味着我们带入上面的式子a+b=a⊕b+2∗(a&b):
得到异或其实就是加法x⊕u=x+u;

所以我们可以得到序列长度为2的序列:[x+u, x]

好啦解释完啦~

代码部分:

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;

ll u, v;
ll x;

int main()
{
	cin >> u >> v;
	if (u > v)
	{
		cout << "-1\n";
	}
	else if (u == v)
	{
		if (!v)
		{
			cout << 0 << endl;
		}
		else
		{
			cout << 1 << endl << v;
		}
	}
	else
	{
		if ((v - u) & 1)
		{
			cout << "-1\n";
		}
		else
		{
			x = (v - u) / 2;
			if (!(u & x))
			{
				cout << "2\n";
				cout << x + u << " " << x << endl;
			}
			else
			{
				cout << "3\n";
				cout << u << " " << x << " " << x << endl;
			}
		}
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

娃娃酱斯密酱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值