既然题目中用到了位运算,那我们就用二进制来解决这道题。
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+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
标签:10,101,题解,ConstructOR,样例,CF1748D,lowbit,aligned,operatorname
From: https://www.cnblogs.com/As-Snow/p/16894871.html