Ehab the Xorcist CodeForces - 1325D

原题链接
考察:构造
思路:
  异或和为u,数值和为v.如何判断不可能成立?

  1. u>v 即不成立.很明显因为u是v的不进位加法.
  2. u&1 != v&1 .正如上面说u是v的不进位加法.进位是不会改变奇偶性的.理性证明就是 v = u + 2*(u&v) u&v得到u哪些位置该进位,把它们左移一位即可.
      那么如何构造最短序列呢?我们需要构造异或和为u,那么u二进制为1的地方一定要有奇数个1.很明显先在序列构造一个u.那么接下来变成了数值和 = v-u,异或和 = 0.需要最短,构造两个v-u>>1即可.
      但这样和样例1不符合,原因是样例1只在u二进制为0处增加一些1,在构造相应位置为1的另一个数,序列长度可缩短为2.如何快速求出满足条件的1?可以发现假设另一个数为x. u+x+x = v && x&u==0 即可满足构造长度为2的序列条件.

Code

#include <iostream> 
#include <cstring>
using namespace std;
typedef long long LL;
LL n,m;
void solve()
{
	if(!m) {puts("0");return;} 
	if(n==m) {printf("%d\n%lld\n",1,n);return;} 
	if(n>m||n%2!=m%2) {printf("%d\n",-1);return;} 
	LL d = m-n>>1ll;
	if(!(d&n)) printf("%d\n%lld %lld\n",2,d,n+d);
	else printf("%d\n%lld %lld %lld\n",3,d,d,n);
}
int main()
{
	scanf("%lld%lld",&n,&m);
	solve();
	return 0;
}

posted @ 2021-05-23 11:26  acmloser  阅读(26)  评论(0编辑  收藏  举报