Codeforces Round 628 (Div. 2) D. Ehab the Xorcist

题目大意

给出两个数 \(u\)​​​​​​ 和 \(v\)​​​​​​,构造一个最短的数组满足数组的异或和为 \(u\)​​​​,和为 \(v\)​​​​,多解输出任意解,不存在解输出 -1。

\((0\leq u,v\leq 1e18)\)

题目分析

先考虑一些特殊情况:

1、不存在解

2、\(u=v~\and~ u\neq0\)

3、\(u=v~\and~u=0\)

情况 2、3 很好处理,答案显然,特判即可,但如何判断不存在解的情况呢?

我们知道异或是不进位的二进制加法,所以显然有 \(u\leq v\),因此当 \(u>v\)​ 时一定无解。除此之外就一定有解了吗?并不是。

我们知道位运算有个经典套路:\(a\oplus b=a|b-a\&b,~a+b=a|b+a\&b\)​​​​​,所以 \(a+b-(a\oplus b)=2(a\&b)\)​​​​,证明留待读者自己完成。这个我真的会证,不过博客是写给自己看的所以就不多逼逼了

易知一定不存在两个数满足它们的异或和与和之差为奇数,又因为异或和加法运算都满足结合律和交换律,所以 \(x_1,x_2,x_3,\dots,x_n\)​​​​​​​​​​​​​​​ 的异或和一定可以转化为两个数 \(a,b\)​​​​​​​ 的异或和,它们的总和也一定能转化为 \(a,b\)​​​​​​​​ 之和,对于两个数的情况不存在解,对于多个数的情况也不可能存在解,从而当 \((v-u)\%2\neq0\) 时,无解。

\((v-u)\%2=0\)​​​​​​​ 时,令 \(p=\dfrac {v-u}2=a\&b,~q=a|b\)​​​​​​​​,显然存在一组长度为 3 的解 \(\{u,p,p\}\)​​​​​​ 满足 \(u\oplus p\oplus p=u,~u+p+p=v\)​​​​​,​​​​​ 但我们要求的是最短的数组,长度为 3 一定是最短吗?有没有长度为 2 的呢?显然是有的。看样例就知道肯定有

假设存在两个数 \(a,b\)​​ 满足 \(a\oplus b=u,~a+b=v\)​​,根据上面提到的套路,我们有 \(p=a\&b=\dfrac {v-u}2,~q=a|b=v-p\)​。

\(p,q\) 已知,则我们可以通过枚举 \(p\)\(q\) 在二进制下的每一位从而确定 \(a\)\(b\)​。

假设这一位为 \(i\),则有四种情况:

1、\(p_i=q_i=0\),则 \(a_i=b_i=0\)

2、\(p_i=0,~q_i=1\),则 \(a_i=1,~b_i=0\)(反过来也行,一样滴);

3、\(p_i=1,~q_i=0\),显然不存在两个数 \(a,b\) 满足 \(a\&b=p,~a|b=q\)

4、\(p_i=q_i=1\),则\(a_i=b_i=1\)

判到 \(q\)​​ 的最后一位停止,如果没出现过情况 3,则存在更短的解 \(\{a,b\}\)​​;否则最短解长度为 3,直接输出 \(\{u,p,p\}\)​​。时间复杂度 \(O(\log p)\)​​。

至此题目就做完了,具体实现细节可参考下方代码。

代码实现

#include<bits/stdc++.h>
using namespace std;
int main(){
	long long u,v;
	cin >> u >> v;
	if(u==v){
		if(u==0){
			cout << 0;
		} 
		else {
			cout << 1 << endl << u;
		}
	}
	else if(u>v){
		cout << -1;
	}
	else {
		long long p=v-u;
		if(p&1){
			cout << -1;
		}
		else {
			p/=2;
			long long q=v-p;
			int flag=1;
			long long a=0;
			for(unsigned long long i=1;i<=q;i<<=1){
				if(p&i){
					if(q&i){
						a+=i;
					}
					else {
						flag=0;
						break;
					}
				}
				else if(q&i) a+=i;
			}
			if(flag){
				printf("2\n%lld %lld",a,v-a);
			}
			else {
				printf("3\n%lld %lld %lld",u,p,p);
			}
		}
	}
}
posted @ 2021-11-12 01:36  olderciyuan  阅读(39)  评论(0)    收藏  举报