CF1748D ConstructOR 题解

可能更好的食用体验

既然题目中用到了位运算,那我们就用二进制来解决这道题。

1.判无解

观察 \(3\,4\,6\) 这个样例,我们将其分解二进制:

\[\begin{aligned} (3)_{10} &= (11)_2 \\ (4)_{10} &= (100)_2\\ (6)_{10} &= (110)_2\\ \end{aligned} \]

我们设 \(\operatorname{lowbit}(x)\) 表示 \(x\) 最末尾的 \(1\) 在第几位,那么我们可以发现一条性质:\(\operatorname{lowbit}(d)\le\operatorname{lowbit}(a\operatorname{ or }b)\)。如果不满足,那么一定无解。

2.构造 \(x\)

我们来分析样例中的第一组数据:

\[\begin{aligned} a &= 1100\\ b &= 100111\\ d &= 101\\ \end{aligned} \]

\[\begin{aligned} 1100&\\ 100111&\\ \text{---------------}\\ 101&\\ 101\;\;&\\ 101\;\;\;\;\;\;\;\;\;\\ \text{---------------}\\ 10101111 \end{aligned} \]

我们可以发现 \(x\) 有若干个 \(d\) 相加得到,并且 \((a\operatorname{or}x )=x\),\((b\operatorname{or}x )=x\),所以一定满足 \(d\,|\,(a\operatorname{or}x)\)\(d\,|\,(a\operatorname{or}x)\)

\(x\) 的构造方法如上所示。设 \(c\gets (a\operatorname{or}b)\),则对于 \(c\) 的每 \(i\) 位二进制位为 \(1\),如果 \(x\) 的第 \(i\) 位也为 \(1\) 则跳过,否则 \(x\gets x+d\times 2^{i-\operatorname{lowbit}(d)}\)

Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
int T,a,b,d,k,x;
void solve(){
	cin>>a>>b>>d;
	k=x=0;//k表示lowbit(d)
	while((d>>k&1)^1)k++;
	for(int i=0;i<30;i++)
		if( ((a|b)>>i&1) && (ans>>i&1)==0 )
			if(i<k)return void(puts("-1"));//判无解
			else x+=(d<<i-k);
	cout<<x<<endl;
}
signed main(){
	cin>>T;
	while(T--)solve();
	return 0;
}

P.s. 应为构造方式比较特殊,所以输出会和样例输出不一样,不要像我一样傻傻的为此去调了二十分钟

样例输出

175
14
-1
-1
2
27
64446
143838208856161791
posted @ 2022-11-16 09:47  ASnown  阅读(124)  评论(0)    收藏  举报